diff --git a/G102-sequence/appmanifest.json b/G102-sequence/appmanifest.json
deleted file mode 100644
index be139ae..0000000
--- a/G102-sequence/appmanifest.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "G102-sequence",
- "short_name": "G102-sequence",
- "start_url": "index.html",
- "display": "fullscreen",
- "orientation": "any",
- "icons": [{
- "src": "icon-16.png",
- "sizes": "16x16",
- "type": "image/png"
- }, {
- "src": "icon-32.png",
- "sizes": "32x32",
- "type": "image/png"
- }, {
- "src": "icon-128.png",
- "sizes": "128x128",
- "type": "image/png"
- }, {
- "src": "icon-256.png",
- "sizes": "144x144",
- "type": "image/png"
- }, {
- "src": "icon-256.png",
- "sizes": "256x256",
- "type": "image/png"
- }]
-}
diff --git a/G102-sequence/bg.mp4 b/G102-sequence/bg.mp4
deleted file mode 100644
index b08ed26..0000000
Binary files a/G102-sequence/bg.mp4 and /dev/null differ
diff --git a/G102-sequence/data.js b/G102-sequence/data.js
deleted file mode 100644
index 2f4833d..0000000
--- a/G102-sequence/data.js
+++ /dev/null
@@ -1 +0,0 @@
-{"project": [null,"Intro",[[0,true,false,false,false,false,false,false,false,false],[1,true,false,false,false,false,false,false,false,false],[2,true,false,false,false,false,false,false,false,false],[3,false,true,true,true,true,true,true,true,true],[4,false,true,true,true,true,true,true,true,false],[5,false,true,true,true,true,true,true,true,false],[6,true,false,false,false,false,false,false,false,false],[7,true,false,false,false,false,false,false,false,false]],[["t0",5,false,[],1,0,null,[["Default",5,false,1,0,false,793688982157584,[["images/sena_ui_frame_result-sheet0.png",699455,0,0,875,720,1,0.5005714297294617,0.5,[],[-0.4146148264408112,-0.3859879970550537,0.05669057369232178,-0.5,0.4994285702705383,-0.3815540075302124,0.4994285702705383,-0.007573008537292481,0.4994285702705383,0.4284909963607788,0.05669057369232178,0.5,-0.4739784300327301,0.4210999608039856,-0.5005714297294617,-0.007573008537292481],0]]]],[["MoveTo",8,920348499201537]],false,false,369380466351656,[],null],["t1",5,false,[],0,0,null,[["Default",5,false,1,0,false,800486011174997,[["images/sena_btn_replay-sheet0.png",89815,0,0,391,174,1,0.5012787580490112,0.5,[],[-0.5012787580490112,-0.5,0.1341402530670166,-0.5,0.4987212419509888,-0.5,0.4987212419509888,-0.5,0.4987212419509888,0.2284250259399414,0.1341402530670166,0.5,-0.5012787580490112,0.2284250259399414,-0.5012787580490112,-0.5],0]]]],[],false,false,113078063989384,[],null],["t2",5,false,[],0,0,null,[["Default",0,false,1,0,false,359527118583899,[["images/asset3-sheet0.png",7266,0,0,82,97,1,0.5,0.5051546096801758,[],[-0.4024389982223511,-0.5051546096801758,0.4024389982223511,-0.5051546096801758,0.4024389982223511,0.4948453903198242,-0.4024389982223511,0.4948453903198242],0],["images/asset3-sheet1.png",10773,0,0,82,97,1,0.5,0.5051546096801758,[],[],0]]]],[],false,false,316569445899063,[],null],["t3",5,false,[826794036185700,449325419484337,850774566536162,233953303989882,584697667322200,915051182566084,709980987140611,864916470115508,671424700857603],3,0,null,[["Default",0,false,1,0,false,766361138730018,[["images/answers-sheet0.png",12383,0,0,199,85,1,0.5025125741958618,0.5058823823928833,[],[],0]]]],[["MoveTo",8,604855247345446],["Fade",9,172183085978858],["DragDrop",10,421888048208530]],false,false,521274050538780,[],null],["t4",7,false,[],0,0,null,null,[],false,false,786570836240034,[],null,[1]],["t5",2,false,[],0,0,null,null,[],false,false,293329078829759,[],null,[]],["t6",1,false,[],0,0,null,null,[],false,false,309246988327533,[],null,[]],["t7",3,false,[418166495958066],1,0,["images/txt_answerss.png",94531,0],null,[["Pin",11,637804778596767]],false,false,609667421047101,[],null],["t8",5,false,[567648729382427,954939568499611,879557559304754,808559794937329,997079567163161,911603245442015,133986401252626],0,0,null,[["Default",0,false,1,0,false,163248314795401,[["images/answers-sheet0.png",12383,0,0,199,85,1,0.5025125741958618,0.5058823823928833,[],[],0],["images/checker_frame-sheet0.png",11183,0,0,199,82,1,0.5025125741958618,0.5,[],[],0]]]],[],false,false,519636697009154,[],null],["t9",5,false,[],0,0,null,[["Default",5,false,1,0,false,157803278794484,[["images/btn_submit-sheet0.png",12137,0,0,301,110,1,0.5016611218452454,0.5,[],[-0.411885529756546,-0.2352940142154694,-0.002908110618591309,-0.5,0.4085628986358643,-0.2352940142154694,0.4958449006080627,0,0.4110568761825562,0.2426469922065735,-0.002908110618591309,0.4779409766197205,-0.4143793284893036,0.2426469922065735,-0.4991673529148102,0],0]]]],[],false,false,588453873694452,[],null],["t10",3,false,[942862735447965],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,111792501546005]],false,false,432979753740528,[],null],["t11",5,false,[],0,0,null,[["Default",5,false,1,0,false,721392848979743,[["images/btn_submit2-sheet0.png",187044,0,0,888,132,1,0.5,0.5,[],[-0.5,0.4549919962882996,0.06428402662277222,-0.5,0.5,0.4549919962882996,0.5,0.5,0.5,0.5,0.06428402662277222,0.5,-0.5,0.5,-0.5,0.5],0]]]],[],false,false,946625081997369,[],null],["t12",5,false,[],1,0,null,[["Default",5,false,1,0,false,721783848790452,[["images/btn_next-sheet0.png",49832,0,0,356,148,1,0.5,0.5,[],[-0.3533200025558472,-0.3626599907875061,-0.009059995412826538,-0.494535505771637,0.3352019786834717,-0.3461750149726868,0.4982730150222778,0,0.3533200025558472,0.3626599907875061,-0.009059995412826538,0.4945359826087952,-0.3352019786834717,0.3461750149726868,-0.4982728660106659,0],0]]]],[["Sine",12,402421837074546]],false,false,818775859313496,[],null],["t13",5,false,[],0,0,null,[["Default",5,false,1,0,false,921392178132129,[["images/btn_play-sheet0.png",134711,0,0,346,346,1,0.5028901696205139,0.5,[],[],0],["images/btn_play-sheet1.png",168,0,0,250,250,1,0.5,0.5,[],[],3]]]],[],false,false,762262472806633,[],null],["t14",0,false,[],0,0,null,null,[],false,false,975221106550751,[],null,[0,0,0,1,1,600,600,10000,1]],["t15",5,false,[],0,0,null,[["Default",5,false,1,0,false,652654928968960,[["images/bg-sheet0.png",1099565,0,0,1400,900,1,0.5,0.5,[],[],1]]]],[],false,false,535930218119366,[],null],["t16",5,false,[],1,0,null,[["Default",5,false,1,0,false,916970518775193,[["images/frame_door-sheet0.png",1822354,0,0,1920,1080,1,0.5,0.5,[],[],0]]]],[["EaseTween",13,688493971614921]],false,false,673749981300323,[],null],["t17",5,false,[],1,0,null,[["Default",5,false,1,0,false,934719015921392,[["images/frame_door_left-sheet0.png",539840,0,0,469,822,1,0.5010660886764526,0.5,[],[-0.498933881521225,-0.4987834393978119,0.4968019127845764,-0.4987834393978119,0.4946699142456055,0.4975669980049133,-0.498933881521225,0.4987829923629761],0]]]],[["MoveTo",8,401776860679972]],false,false,153559747848512,[],null],["t18",5,false,[],1,0,null,[["Default",5,false,1,0,false,742259468763493,[["images/frame_door_right-sheet0.png",543214,0,0,467,821,1,0.5010706782341003,0.5006090402603149,[],[-0.5010706782341003,-0.5006090402603149,0.4967883229255676,-0.4993910193443298,0.4989293217658997,0.4993909597396851,-0.4967880249023438,0.4969549775123596],0]]]],[["MoveTo",8,142691375562698]],false,false,951982130871283,[],null],["t19",5,false,[],1,0,null,[["Default",5,false,1,0,false,596630541764877,[["images/hand_right-sheet0.png",64594,0,0,155,346,1,0.5032258033752441,0.5,[],[],0]]]],[["Pin",11,481474855082544]],false,false,888342496691520,[],null],["t20",5,false,[],1,0,null,[["Default",0,false,1,0,false,756321102172276,[["images/hand_left-sheet0.png",70922,0,0,193,346,1,0.5025906562805176,0.5,[],[],0]]]],[["Pin",11,120839381152826]],false,false,928771787327892,[],null],["t21",5,false,[],0,0,null,[["Default",5,false,1,0,false,781887315764771,[["images/ao_vang_quan_xanh-sheet0.png",1040452,0,0,774,922,1,0.5,0.5,[],[-0.2894060015678406,0.1757050156593323,0.03746801614761353,-0.4989154040813446,0.2945740222930908,0.2342730164527893,0.1860470175743103,-0.005423009395599365,0.3888890147209168,-0.1659440100193024,0.03746801614761353,0.4707159996032715,-0.3255810141563416,-0.1561819911003113,-0.2080099880695343,-0.005423009395599365],0]]]],[],false,false,515036206907780,[],null],["t22",5,false,[],0,0,null,[["Default",5,false,1,0,false,430849449557794,[["images/sprite-sheet0.png",168,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,787263586433186,[],null],["t23",5,false,[],0,0,null,[["Default",5,false,1,0,false,672711485213709,[["images/khung_thoai-sheet0.png",1053981,0,0,1381,809,1,0.4989138245582581,0.5018541216850281,[],[0.4622311592102051,-0.003646135330200195,0.4008821845054627,0.3225188851356506,0.002108156681060791,0.3440238833427429,-0.4027993083000183,0.3296868801116943,-0.4723289310932159,-0.003646135330200195,-0.4477890133857727,-0.412248432636261,0.002108156681060791,-0.4695960283279419,0.4438261985778809,-0.4014961123466492],0]]]],[],false,false,445582981850455,[],null],["t24",5,false,[],1,0,null,[["Default",5,false,1,0,false,185542005979120,[["images/khung_thoai2-sheet0.png",31535,0,0,304,283,1,0.5197368264198303,0.5017668008804321,[],[0.4802631735801697,-0.003533810377120972,0.4802631735801697,0.3180211782455444,0.2927631735801697,0.3392221927642822,-0.3585528135299683,0.3250882029533386,-0.4703947305679321,-0.003533810377120972,-0.4309210181236267,-0.406360387802124,0.2927631735801697,-0.4628975093364716,0.4802631735801697,-0.395759791135788],0]]]],[["Pin",11,512817705122333]],false,false,469674199718312,[],null],["t25",5,false,[],0,0,null,[["Default",5,false,1,0,false,127783747161360,[["images/khung_diem-sheet0.png",16479,0,0,245,100,1,0.5020408034324646,0.5,[],[],0]]]],[],false,false,811404919858500,[],null],["t26",5,false,[],1,0,null,[["Default",5,false,1,0,false,859799537201858,[["images/avatar-sheet0.png",1500573,0,0,1024,1024,1,0.5,0.5,[],[],1]]]],[["Pin",11,171038971830502]],false,false,837535844611312,[],null],["t27",5,false,[],0,0,null,[["Default",5,false,1,0,false,552699784638859,[["images/star_-sheet0.png",22582,0,0,127,134,1,0.5039370059967041,0.5,[],[],0]]]],[],false,false,412169584854831,[],null],["t28",5,false,[],0,0,null,[["Default",0,false,1,0,false,739926277400680,[["images/frame_score-sheet0.png",5875,1,134,270,64,1,0.5,0.5,[],[0.3552079796791077,-0.5,0.5,0.5,0.5,0.5,-0.5,0.5],0],["images/frame_score-sheet0.png",5875,1,1,316,64,1,0.5,0.5,[],[0.2940059900283814,-0.5,0.5,0.5,0.4744920134544373,0.5,-0.5,0.5],0],["images/frame_score-sheet0.png",5875,1,67,305,65,1,0.5016393661499023,0.5076923370361328,[],[0.3341176509857178,-0.5076923370361328,0.4983606338500977,0.4923076629638672,0.4983606338500977,0.4923076629638672,-0.5016393661499023,0.4923076629638672],0]]]],[],false,false,819525228363299,[],null],["t29",5,false,[],0,0,null,[["Default",5,false,1,0,false,164220506748003,[["images/dong_ho-sheet0.png",24920,0,0,107,131,1,0.5046728849411011,0.5038167834281921,[],[],0]]]],[],false,false,854740896764654,[],null],["t30",5,false,[],0,0,null,[["Default",5,false,1,0,false,116956179455582,[["images/coin-sheet0.png",17848,0,0,100,98,1,0.5,0.5,[],[-0.3600000143051148,-0.357142984867096,0,-0.5,0.3500000238418579,-0.3469389975070953,0.5,0,0.3600000143051148,0.357142984867096,0,0.5,-0.3499999940395355,0.3469390273094177,-0.5,0],0]]]],[],false,false,305346690752957,[],null],["t31",3,false,[940286636988100],3,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,834701880706737],["Fade",9,958123565456535],["MoveTo",8,973282322763825]],false,false,728262842526683,[],null],["t32",3,false,[344679164944695],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,128644578527300]],false,false,522216010047558,[],null],["t33",3,false,[731123512951619],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,516508734324126]],false,false,340765955288849,[],null],["t34",3,false,[692803175473927],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,545779800810831]],false,false,591329026570186,[],null],["t35",3,false,[826587350959856],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,553083715854589]],false,false,708446667476819,[],null],["t36",6,false,[],0,0,null,null,[],false,false,818073484425726,[],null,["default"]],["t37",5,false,[],0,0,null,[["Default",5,false,1,0,false,878733427822656,[["images/sena_ui_frame_intro-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],4]]]],[],false,false,722501346055698,[],null],["t38",3,false,[529603772061051],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,762382317930428]],false,false,533138744901290,[],null],["t39",3,false,[472340567293658],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,585006722065273]],false,false,462260847926939,[],null],["t40",3,false,[623658190405060],1,0,["images/txt_instructions.png",148918,0],null,[["Pin",11,158286730532340]],false,false,325060752227160,[],null],["t41",4,false,[],1,0,null,null,[["Pin",11,983903129678407]],false,false,194612180994682,[],null],["t42",4,false,[],1,0,null,null,[["Pin",11,253592077507409]],false,false,557129552997296,[],null],["t43",4,false,[],1,0,null,null,[["Pin",11,575662582966304]],false,false,454879628680945,[],null],["t44",5,false,[],1,0,null,[["Default",5,false,1,0,false,514358608673893,[["images/sena_title_leaderboard-sheet0.png",15453,0,0,378,86,1,0.5,0.5,[],[-0.4920634925365448,-0.4651162922382355,0,-0.4767442047595978,0.4814810156822205,-0.4186046123504639,0.4867720007896423,0.4418600201606751,0,0.4767439961433411,-0.4841269850730896,0.4302330017089844],0]]]],[["Pin",11,291293272927256]],false,false,678289200328767,[],null],["t45",4,false,[],1,0,null,null,[["Pin",11,210576751902792]],false,false,544994622581180,[],null],["t46",5,false,[],1,0,null,[["Default",5,false,1,0,false,768984330229325,[["images/sena_ui_frame_leaderboard-sheet0.png",819163,0,0,1004,711,1,0.5,0.5007032155990601,[],[-0.2545090019702911,0.2284637689590454,0,-0.301298201084137,0.2555109858512878,0.2254867553710938,0.1833670139312744,-0.0007032155990600586,0.4979959726333618,0.493344783782959,-0.4989979863166809,0.4963207840919495,-0.218436986207962,-0.0007032155990600586],0]]]],[["MoveTo",8,138738316639915]],false,false,999135729758638,[],null],["t47",5,false,[],2,0,null,[["Default",5,false,1,0,false,336741884175694,[["images/sena_btn_exit-sheet0.png",54942,0,0,353,110,1,0.5014164447784424,0.5,[],[-0.4819989502429962,-0.4772726893424988,-0.006270438432693481,-0.5,0.4014965295791626,-0.3863639831542969,0.4985835552215576,0,0.4014965295791626,0.3863639831542969,-0.006270438432693481,0.5,-0.4819989502429962,0.4772729873657227],0]]]],[["Pin",11,560194038481806],["Sine",12,525138810006428]],false,false,502189296415963,[],null],["t48",5,false,[],1,0,null,[["Default",0,false,1,0,false,194609735200710,[["images/sena_ui_item_bg-sheet0.png",193967,1,1,710,89,1,0.5,0.5056179761886597,[],[-0.49203822016716,-0.4551129639148712,0,-0.4955169856548309,0.4920380115509033,-0.4551129639148712,0.4872609972953796,0.4135740399360657,0,0.4438770413398743,-0.485668808221817,0.4034730195999146],0],["images/sena_ui_item_bg-sheet0.png",193967,1,92,710,89,1,0.5,0.5056179761886597,[],[-0.49203822016716,-0.4551129639148712,0,-0.4955169856548309,0.4920380115509033,-0.4551129639148712,0.4872609972953796,0.4135740399360657,0,0.4438770413398743,-0.485668808221817,0.4034730195999146],0],["images/sena_ui_item_bg-sheet0.png",193967,1,183,710,89,1,0.5,0.5056179761886597,[],[-0.49203822016716,-0.4551129639148712,0,-0.4955169856548309,0.4920380115509033,-0.4551129639148712,0.4872609972953796,0.4135740399360657,0,0.4438770413398743,-0.485668808221817,0.4034730195999146],0]]]],[["Pin",11,977629152659308]],false,false,893411604042085,[],null],["t49",4,false,[],1,0,null,null,[["Pin",11,384847762937375]],false,false,631581457940413,[],null],["t50",5,false,[],1,0,null,[["Default",5,false,1,0,false,442906146329397,[["images/sena_ui_item_bg_user_rank-sheet0.png",140970,0,0,906,106,1,0.5,0.5,[],[-0.49203822016716,-0.449999988079071,0,-0.4900000095367432,0.4920380115509033,-0.449999988079071,0.4872609972953796,0.4200000166893005,0,0.449999988079071,-0.485668808221817,0.4100000262260437],0]]]],[["Pin",11,735755786104278]],false,false,364823197906140,[],null],["t51",5,false,[],2,0,null,[["Default",5,false,1,0,false,365534682662000,[["images/sena_btn_leaderboard-sheet0.png",602377,0,0,711,706,1,0.502109706401825,0.5,[],[-0.502109706401825,-0.5,0.4978902935981751,-0.5,0.4978902935981751,-0.5,0.4978902935981751,-0.5,0.4978902935981751,0.5,0.4978902935981751,0.5,-0.502109706401825,0.5,-0.502109706401825,-0.5],0]]]],[["Sine",12,416492860918880],["Pin",11,970999859717446]],false,false,104446272667811,[],null],["t52",5,false,[],1,0,null,[["Default",0,false,1,0,false,361663207643924,[["images/sena_ui_number_rank-sheet1.png",8104,0,0,80,73,1,0.5,0.5068492889404297,[],[-0.449999988079071,-0.4520547986030579,0,-0.5068492889404297,0.4374999403953552,-0.4383561015129089,0.4874999523162842,-0.0136982798576355,0.4374999403953552,0.4246577024459839,0,0.4794517159461975,-0.4375,0.4246577024459839,-0.5,-0.0136982798576355],0],["images/sena_ui_number_rank-sheet0.png",9587,0,0,81,75,1,0.5061728358268738,0.5066666603088379,[],[-0.4561728239059448,-0.4518721699714661,-0.006172835826873779,-0.5066666603088379,0.4313271045684815,-0.4381734728813171,0.4813271164894104,-0.0135156512260437,0.4313271045684815,0.4248403310775757,-0.006172835826873779,0.4796343445777893,-0.4436728358268738,0.4248403310775757,-0.5061728358268738,-0.0135156512260437],0],["images/sena_ui_number_rank-sheet2.png",9308,0,0,80,73,1,0.5,0.5068492889404297,[],[-0.449999988079071,-0.4520547986030579,0,-0.5068492889404297,0.4374999403953552,-0.4383561015129089,0.4874999523162842,-0.0136982798576355,0.4374999403953552,0.4246577024459839,0,0.4794517159461975,-0.4375,0.4246577024459839,-0.5,-0.0136982798576355],0]]]],[["Pin",11,797661570651107]],false,false,508062575001136,[],null],["t53",5,false,[],1,0,null,[["Default",5,false,1,0,false,448852033052573,[["images/btn_next-sheet0.png",49832,0,0,356,148,1,0.5,0.5,[],[-0.4410111904144287,-0.3581079840660095,0,-0.4932432472705841,0.4269660115242004,-0.3243240118026733,0.4662920236587524,0,0.4101120233535767,0.2837839722633362,0,0.4189190268516541,-0.4269663095474243,0.3243240118026733,-0.4971910119056702,0],0]]]],[["Sine",12,778929599409288]],false,false,544411999059092,[],null],["t54",4,false,[],1,0,null,null,[["Pin",11,965180744558262]],false,false,257844620587332,[],null],["t55",4,false,[],1,0,null,null,[["Pin",11,668111541658451]],false,false,865512087815474,[],null],["t56",4,false,[],1,0,null,null,[["Pin",11,983629863781910]],false,false,452023984157524,[],null],["t57",4,false,[],1,0,null,null,[["Pin",11,621704806901910]],false,false,108820901806782,[],null],["t58",5,false,[],2,0,null,[["Default",5,false,1,0,false,325577231432987,[["images/sena_fx_wrong_mark-sheet0.png",27271,0,0,140,140,1,0.5,0.5,[],[-0.08866998553276062,0.05115598440170288,0,-0.05821299552917481,0.08374398946762085,0.05821299552917481,0.07635402679443359,-0.001763999462127686,0.1009849905967712,-0.03351700305938721,0,0.1005499958992004,-0.105910986661911,-0.02645999193191528,-0.08374398946762085,-0.001763999462127686],0]]]],[["Fade",9,938090566638553],["Pin",11,922984705911085]],false,false,786659809200098,[],null],["t59",5,false,[],2,0,null,[["Default",5,false,1,0,false,199500828138837,[["images/sena_fx_correct_mark-sheet0.png",31182,0,0,140,140,1,0.5,0.5071428418159485,[],[-0.03694498538970947,-0.01037183403968811,0,-0.05661284923553467,0.4187189936637878,-0.4319769442081451,0.08374398946762085,-0.004931867122650147,0,0.133790135383606,-0.280788004398346,0.2725121378898621,-0.03940901160240173,-0.004931867122650147],0]]]],[["Fade",9,351180598525433],["Pin",11,692899677986212]],false,false,185378619927884,[],null],["t60",4,false,[],0,0,null,null,[],false,false,755298125283785,[],null],["t61",5,true,[],1,0,null,null,[["Pin",11,943483328563522]],false,false,280951626473829,[],null]],[[61,11,28,1,27]],[["Intro",1200,1200,false,"Intro",616521222166130,[["Layer 0",0,377782185880785,true,[255,255,255],true,0,0,1,false,false,0,0,0,[[[600,600,0,2110.940673828125,1357.033325195313,0,0,1,0.5,0.5,0,0,[]],15,14,[],[],[0,"Default",0,1]],[[-2504,-1046,0,875,720,0,0,1,0.5005714297294617,0.5,0,0,[]],0,1,[],[[1,1200,0,0]],[0,"Default",0,1]],[[-805,-1058,0,445,260,0,0,1,0.5,0.5,0,0,[]],10,20,[["A"]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","38",46,0,1,1,1,0,0,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",8]],[[-3161,439,0,543.1068725585938,951.884521484375,0,0,1,0.5010660886764526,0.5,0,0,[]],17,29,[],[[1,600,0,0]],[0,"Default",0,1]],[[-2618,439,0,543.1069946289063,951.885009765625,0,0,1,0.5010706782341003,0.5006090402603149,0,0,[]],18,30,[],[[1,600,0,0]],[0,"Default",0,1]],[[-2796,410,0,155,346,0,0,1,0.5032258033752441,0.5,0,0,[]],19,28,[],[[]],[0,"Default",1,1]],[[-2997,410,0,193,346,0,0,1,0.5025906562805176,0.5,0,0,[]],20,34,[],[[]],[0,"Default",0,1]],[[-2890,414,0,2229.62109375,1254.161987304688,0,0,1,0.5,0.5,0,0,[]],16,21,[],[[0,1,0,"current","2",1,"0,0",0,0,1,0,""]],[0,"Default",0,1]],[[600,600.0000610351563,0,2522.37109375,1467.688598632813,0,0,0.699999988079071,0.5,0.5,0,0,[]],37,24,[],[],[0,"Default",0,1]]],[]],["Scenario",1,283182443100177,true,[255,255,255],true,0,0,1,false,false,0,0,0,[[[598.792236328125,598,0,1111.969360351563,716.6204223632813,0,0,1,0.4989138245582581,0.5018541216850281,0,0,[]],23,40,[],[],[0,"Default",0,1]],[[598.792236328125,993,0,251.352294921875,104.4947738647461,0,0,1,0.5,0.5,0,0,[]],53,68,[],[[1,2,0,1,1,0,0,10,10]],[0,"Default",0,1]],[[597.792236328125,670,0,967,423,0,0,1,0.5,0.5,0,0,[]],60,51,[],[],["Text",0,"bold 36pt Arial","rgb(0,0,0)",1,1,4,0,0]]],[]]],[],[]],["Result",1200,1200,false,"Result",499473104045564,[["Layer 0",0,215265142032865,true,[255,255,255],true,0,0,1,false,false,0,0,0,[[[600,600,0,1625.765380859375,1045.135009765625,0,0,1,0.5,0.5,0,0,[]],15,11,[],[],[0,"Default",0,1]],[[600.5,628.5,0,875,720,0,0,1,0.5005714297294617,0.5,0,0,[]],0,22,[],[[1,1200,0,0]],[0,"Default",0,1]],[[-544,-469,0,445,273,0,0,1,0.5,0.5,0,0,[]],10,25,[["A"]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","38",46,0,1,1,1,0,0,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",8]],[[602.5,400.5,0,712.9652709960938,105.9813232421875,0,0,1,0.5,0.5,0,0,[]],11,26,[],[[]],[0,"Default",0,1]],[[600.5,278.5,0,127,134,0,0,1,0.5039370059967041,0.5,0,0,[]],27,19,[],[[]],[0,"Default",0,1]],[[450.5,278.5,0,127,134,0,0,1,0.5039370059967041,0.5,0,0,[]],27,27,[],[[]],[0,"Default",0,1]],[[750.5,278.5,0,127,134,0,0,1,0.5039370059967041,0.5,0,0,[]],27,41,[],[[]],[0,"Default",0,1]],[[748.5,843.5,0,222,130,0,0,1,0.5,0.5,0,0,[]],38,53,[["score"]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","200",1.2,0,0,1,1,0,1,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",15]],[[450.5,839.5,0,292,130,0,0,1,0.5,0.5,0,0,[]],39,54,[[""]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","Score:",1.2,0,2,1,1,0,1,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",15]],[[450.5,695.5,0,292,130,0,0,1,0.5,0.5,0,0,[]],39,55,[[""]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","Correct:",1.2,0,2,1,1,0,1,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",15]],[[747.5,700.5,0,222,130,0,0,1,0.5,0.5,0,0,[]],40,56,[["A"]],[[]],[55,67,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","38",1.2,0,0,1,1,0,0,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,32,1],\"\"data\"\":[[[12],[13],[14],[16],[17],[18],[19],[20],[21],[22],[23],[24],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[53]],[[\"\"il.|ị\"\"],[\"\"I,:!Ị\"\"],[\"\";'\"\"],[\"\"Ỉì\"\"],[\"\"`ÍÌíỉ\"\"],[\"\"j()[]\"\"],[\"\"-\"\"],[\"\"/\"\"],[\"\"t\"\"],[\"\"1°\"\"],[\"\"fr*Ĩĩ\"\"],[\"\"\\\"\"\"\"],[\"\"Jhnuz09úùụủũ\"\"],[\"\"Faceks235678$áàảạãăằắặẳẵâầấậẩẫéèẻẹẽêềếệểễ\"\"],[\"\"Ldgq?+=<>\"\"],[\"\"bp4~#\"\"],[\"\"EPovxy£€ÉÈẺẸẼÊỀẾỆỂỄóòọỏõôồốộổỗýỳỵỷỹ\"\"],[\"\"HNTU_ÚÙỤỦŨđ\"\"],[\"\"SZ\"\"],[\"\"BD\"\"],[\"\"C\"\"],[\"\"KRưừứựửữ\"\"],[\"\"GVXY&ÝỲỴỶỸ\"\"],[\"\"MĐơờớợởỡ\"\"],[\"\"OÓÒỌỎÕÔỒỐỘỔỖ\"\"],[\"\"AQÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"m\"\"],[\"\"w\"\"],[\"\"%\"\"],[\"\"ƠỜỚỢỞỠ\"\"],[\"\"W@\"\"]]]}",8]],[[600.5,551.5,0,140.2151336669922,139.2290954589844,0,0,1,0.502109706401825,0.5,0,0,[]],51,67,[],[[1,2,0,1,1,0,0,5,5],[]],[0,"Default",0,1]]],[]],["Leaderboard",1,877682455070534,true,[255,255,255],true,0,0,1,false,false,0,0,0,[[[600,599.9999389648438,0,1625.765380859375,1045.135009765625,0,0,1,0.5,0.5,0,0,[]],15,38,[],[],[0,"Default",0,1]],[[603,528.9999389648438,0,904.3123168945313,694.447021484375,0,0,1,0.5,0.5007032155990601,0,0,[]],46,12,[],[[1,1200,0,0]],[0,"Default",0,1]],[[609.4100341796875,404.3887329101563,0,786.626220703125,95.22135925292969,0,0,1,0.5,0.5056179761886597,0,0,[]],48,42,[],[[]],[0,"Default",0,1]],[[553,395.6845092773438,0,400.8202514648438,88,0,0,1,0.5,0.5,0,0,[]],42,43,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[803,399.432861328125,0,210.3880004882813,88,0,0,1,0.5,0.5,0,0,[]],41,44,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[609.4100341796875,500.6133422851563,0,786.626220703125,95.22135925292969,0,0,1,0.5,0.5056179761886597,0,0,[]],48,50,[],[[]],[0,"Default",0,1]],[[553,494.7214660644531,0,400.8202514648438,88,0,0,1,0.5,0.5,0,0,[]],42,57,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[803,494.7214660644531,0,210.3880004882813,88,0,0,1,0.5,0.5,0,0,[]],41,58,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[606.8521728515625,600.946044921875,0,786.626220703125,95.22135925292969,0,0,1,0.5,0.5056179761886597,0,0,[]],48,59,[],[[]],[0,"Default",0,1]],[[553,599.3139038085938,0,400.8202514648438,88,0,0,1,0.5,0.5,0,0,[]],42,60,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[803,597.4390869140625,0,210.3880004882813,88,0,0,1,0.5,0.5,0,0,[]],41,61,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",0,1,4,0,0]],[[607,785.9999389648438,0,786.57666015625,102.4394989013672,0,0,1,0.5,0.5,0,0,[]],50,62,[],[[]],[0,"Default",0,1]],[[573,784.9999389648438,0,400.8200073242188,88,0,0,1,0.5,0.5,0,0,[]],45,63,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,51)",0,1,4,0,0]],[[803,785.9999389648438,0,210.3880615234375,88,0,0,1,0.5,0.5,0,0,[]],49,64,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,51)",0,1,4,0,0]],[[354.9056091308594,394.74853515625,0,105.1577758789063,88,0,0,1,0.5,0.5,0,0,[]],43,65,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,51,0)",1,1,4,0,0]],[[349.9223022460938,400.6976928710938,0,80,73,0,0,1,0.5,0.5068492889404297,0,0,[]],52,66,[],[[]],[0,"Default",0,1]],[[600.5,928.9999389648438,0,353,110,0,0,1,0.5014164447784424,0.5,0,0,[]],47,46,[],[[],[1,2,0,1,0,0,0,5,5]],[0,"Default",0,1]],[[1044,608.9999389648438,0,100,94,0,0,1,0.5,0.5,0,0,[]],43,2,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,0,0)",1,1,4,0,0]],[[933,784.9999389648438,0,100,88,0,0,1,0.5,0.5,0,0,[]],54,10,[],[[]],["Text",0,"bold 20pt Arial","rgb(0,0,0)",0,1,4,0,0]]],[]]],[],[]],["Game",1200,1200,false,"Game",288730111597454,[["Layer 0",0,763235347287340,true,[255,255,255],true,0,0,1,false,false,0,0,0,[[[600,600,0,2197.21728515625,1412.496948242188,0,0,1,0.5,0.5,0,0,[]],15,37,[],[],[0,"Default",0,1]],[[212.0301818847656,656,0,199,85,0,0,1,0.5025125741958618,0.5058823823928833,0,0,[]],3,3,[[0],[0],[0],[0],[0],[""],[0],[0],[0]],[[1,1200,0,0],[1,0.5,0,0,0],[0,1]],[0,"Default",0,1]],[[472.0301513671875,656,0,199,85,0,0,1,0.5025125741958618,0.5058823823928833,0,0,[]],3,4,[[0],[0],[0],[0],[0],[""],[0],[0],[0]],[[1,1200,0,0],[1,0.5,0,0,0],[0,1]],[0,"Default",0,1]],[[732.0301513671875,656,0,199,85,0,0,1,0.5025125741958618,0.5058823823928833,0,0,[]],3,5,[[0],[0],[0],[0],[0],[""],[0],[0],[0]],[[1,1200,0,0],[1,0.5,0,0,0],[0,1]],[0,"Default",0,1]],[[992.0301513671875,656,0,199,85,0,0,1,0.5025125741958618,0.5058823823928833,0,0,[]],3,6,[[0],[0],[0],[0],[0],[""],[0],[0],[0]],[[1,1200,0,0],[1,0.5,0,0,0],[0,1]],[0,"Default",0,1]],[[-823,762,0,199,85,0,0,1,0.5025125741958618,0.5058823823928833,0,0,[]],8,9,[[""],[0],[0],[0],[0],[0],[""]],[],[0,"Default",0,1]],[[1061,181,0,245,100,0,0,1,0.5020408034324646,0.5,0,0,[]],25,33,[],[],[0,"Default",0,1]],[[1061,74,0,245,100,0,0,1,0.5020408034324646,0.5,0,0,[]],25,35,[],[],[0,"Default",0,1]],[[576,285,0,366.4969177246094,366.4969177246094,0,0,1,0.5,0.5,0,0,[]],26,36,[],[[]],[1,"Default",0,1]],[[625,320,0,554.1467895507813,525.3408813476563,0,0,1,0.5197368264198303,0.5017668008804321,0,0,[]],24,32,[],[[]],[1,"Default",0,1]],[[953.46435546875,176.0383911132813,0,78.64425659179688,96.28408813476563,0,0,1,0.5046728849411011,0.5038167834281921,0,0,[]],29,48,[],[],[0,"Default",0,1]],[[952.6445922851563,69.86495208740234,0,88.87046051025391,87.09305572509766,0,0,1,0.5,0.5,0,0,[]],30,49,[],[],[0,"Default",0,1]],[[600.3480224609375,816.7940673828125,0,209.5281219482422,76.57205963134766,0,0,1,0.5016611218452454,0.5,0,0,[]],9,17,[],[],[0,"Default",0,1]],[[212,660,0,168,90,0,0,1,0.5,0.5,0,0,[]],55,18,[],[[]],["Text",0,"bold 36pt Arial","rgb(255,255,255)",1,1,4,0,0]],[[1072,184,0,179,79,0,0,1,0.5,0.5,0,0,[]],56,8,[],[[]],["Text",0,"bold 36pt Arial","rgb(0,0,0)",1,1,4,0,0]],[[1062,77,0,179,79,0,0,1,0.5,0.5,0,0,[]],57,16,[],[[]],["Text",0,"bold 36pt Arial","rgb(0,0,0)",1,1,4,0,0]],[[-2055.5,-971.5,0,120,120,0,0,1,0.5,0.5,0,0,[]],58,23,[],[[1,0.5,0.5,0.5,1],[]],[0,"Default",0,1]],[[-1856.5,-1044.5,0,120,120,0,0,1,0.5,0.5071428418159485,0,0,[]],59,39,[],[[1,0.5,0.5,0.5,1],[]],[0,"Default",0,1]]],[]],["popup",1,663433178020691,true,[255,255,255],true,0,0,1,false,false,0,0,0,[],[]]],[],[]]],[["Intro",[[1,"isSoundOn",0,0,false,false,442953855116895,false],[0,null,false,null,568259272870611,[[5,14,null,2,false,false,false,186379404697622,false,[[1,[2,"startPharse"]]]]],[[17,15,"MoveTo",768947180669655,false,[[0,[0,-1500]],[0,[0,0]]]],[18,15,"MoveTo",580304791974762,false,[[0,[0,1500]],[0,[0,0]]]]]],[0,null,false,null,458451448268050,[[-1,16,null,1,false,false,false,863122307739689,false]],[[37,17,null,434848314125825,false,[[3,1]]],[-1,18,null,620867513776422,false,[[5,[2,"Scenario"]],[3,0]]],[6,19,null,298699222456896,false,[[1,[2,"window['TDVTriger'] = this; tdv_sdk.init();"]]]],[20,20,"Pin",780961716242546,false,[[4,17],[3,0]]],[19,20,"Pin",403194687283405,false,[[4,18],[3,0]]],[-1,21,null,461445367495731,false,[[0,[0,4]]]],[-1,18,null,144805927854091,false,[[5,[2,"Scenario"]],[3,1]]],[37,17,null,494694103757318,false,[[3,0]]],[60,22,null,636748846344677,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getInstructions()"]]]]]]]],[0,null,false,null,486426756367022,[[4,24,null,1,false,false,false,670161933885087,false]],[[14,25,null,843512926307037,false,[[2,["click",false]],[3,0],[0,[0,0]],[1,[2,""]]]]],[[0,null,false,null,244668239889283,[[-1,26,null,0,false,false,false,230398979810349,false,[[5,[2,"Scenario"]]]],[17,27,"MoveTo",0,false,true,false,675924193397283,false]],[[-1,18,null,276020627276302,false,[[5,[2,"Scenario"]],[3,0]]],[5,28,null,226604710621482,false,[[1,[2,"startPharse"]],[13]]]]]]],[0,null,false,null,276975554797051,[[17,29,"MoveTo",1,false,false,false,748565159715845,false]],[[16,30,"EaseTween",953869544948119,false]]],[0,null,false,null,613766865043707,[[16,31,"EaseTween",1,false,false,false,369940328015561,false]],[[-1,32,null,706579825763397,false,[[6,"Game"]]]]],[0,null,false,null,900280004141882,[[36,33,null,1,false,false,false,544328831737618,false]],[]]]],["Game",[[1,"posX",0,0,false,false,840115760333849,false],[1,"posY",0,0,false,false,787851447363292,false],[1,"count",0,0,false,false,546518550564693,false],[1,"result",0,0,false,false,763635704941594,false],[1,"userSentence",1,"",false,false,575011151170447,false],[1,"wordsPlaced",0,0,false,false,155057269422608,false],[1,"isSelect",0,0,false,false,164948275365920,false],[1,"countCorrect",0,0,false,false,342246246742621,false],[1,"numQuestions",0,0,false,false,778150987044228,false],[1,"wordLength",0,0,false,false,399659242084404,false],[1,"gameState",1,"",false,false,106299408518362,false],[1,"score",0,0,false,false,185297949758731,false],[1,"bonus",0,0,false,false,844277613114017,false],[1,"total",0,0,false,false,324044981108861,false],[1,"timer",0,0,false,false,754110356780788,false],[0,null,false,null,138976088495164,[[3,29,"MoveTo",1,false,false,false,626174270477318,false]],[[-1,34,null,404560897934788,false,[[11,"gameState"],[7,[2,"playing"]]]],[3,35,null,754176374676061,false,[[10,0],[3,0]]],[3,36,null,459269065613438,false,[[10,3],[7,[0,0]]]],[3,37,null,126888082310446,false,[[0,[0,0]]]]]],[0,null,false,null,549205817072564,[[-1,16,null,1,false,false,false,597870668036321,false]],[[6,19,null,208416657380260,false,[[1,[2,"tdv_sdk.init()"]]]],[-1,18,null,676243385464497,false,[[5,[2,"popup"]],[3,0]]],[57,22,null,853553313213239,false,[[7,[23,"score"]]]],[56,22,null,962329655518548,false,[[7,[23,"timer"]]]],[-1,34,null,743312706294712,false,[[11,"gameState"],[7,[2,"playing"]]]],[5,28,null,971892219606647,false,[[1,[2,"loadQuestion"]],[13]]]]],[0,null,false,null,902035289977245,[[5,14,null,2,false,false,false,574674860513630,false,[[1,[2,"loadQuestion"]]]]],[[3,38,null,887835609193466,false],[8,38,null,300546270054345,false],[55,39,null,360452655746176,false],[6,19,null,554913326892535,false,[[1,[2,"tdv_sdk.resetPlacedWords()"]]]],[6,19,null,677280751778349,false,[[1,[2,"tdv_sdk.loadQuestions();"]]]],[-1,34,null,798686908172641,false,[[11,"gameState"],[7,[2,"playing"]]]],[-1,34,null,543327033698101,false,[[11,"wordsPlaced"],[7,[0,0]]]],[-1,34,null,542853961477086,false,[[11,"count"],[7,[20,6,23,false,null,[[2,"tdv_sdk.getWordsCount()"]]]]]]],[[0,null,false,null,477383250044862,[[-1,40,null,0,true,false,false,623370903418676,false,[[0,[20,6,23,false,null,[[2,"tdv_sdk.getBlankCount()"]]]]]]],[[-1,34,null,218198095960948,false,[[11,"posX"],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCenteredPosX("],[19,41]],[2,")"]]]]]]],[-1,34,null,432443069999196,false,[[11,"posY"],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCenteredPosY("],[19,41]],[2,")"]]]]]]],[-1,42,null,739353968447079,false,[[4,3],[5,[0,0]],[0,[23,"posX"]],[0,[23,"posY"]]]],[3,36,null,131719618020526,false,[[10,5],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.missingWords["],[19,41]],[2,"]"]]]]]]],[3,36,null,555164331182892,false,[[10,6],[7,[0,-1]]]],[3,36,null,927582884892801,false,[[10,1],[7,[20,3,43,false,null]]]],[3,36,null,396050326510876,false,[[10,2],[7,[20,3,44,false,null]]]],[3,36,null,717468098169697,false,[[10,7],[7,[20,3,43,false,null]]]],[3,36,null,676689922486802,false,[[10,8],[7,[20,3,44,false,null]]]],[-1,42,null,621163829530712,false,[[4,55],[5,[0,0]],[0,[20,3,43,false,null]],[0,[4,[5,[20,3,44,false,null],[6,[0,2],[7,[20,3,45,false,null],[0,180]]]],[0,2]]]]],[55,20,"Pin",880375788473090,false,[[4,3],[3,0]]],[55,22,null,820191162188885,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.missingWords["],[19,41]],[2,"]"]]]]]]],[55,46,null,823092806237741,false,[[0,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getFontSizeByIndex("],[19,41]],[2,", 36)"]]]]]]]]],[0,null,false,null,813488736654379,[[-1,40,null,0,true,false,false,130912375902097,false,[[0,[23,"count"]]]]],[[-1,34,null,743202531348701,false,[[11,"posX"],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCenteredPosX("],[19,41]],[2,")"]]]]]]],[-1,34,null,247210682508678,false,[[11,"posY"],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCheckerBaseY("],[19,41]],[2,")"]]]]]]],[-1,42,null,433551327079829,false,[[4,8],[5,[0,0]],[0,[23,"posX"]],[0,[23,"posY"]]]],[8,36,null,968732523172222,false,[[10,6],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCorrectWordByIndex("],[19,41]],[2,")"]]]]]]],[8,36,null,106836256875377,false,[[10,4],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.isPresetSlot("],[19,41]],[2,")"]]]]]]],[8,36,null,347124458457631,false,[[10,3],[7,[19,41]]]],[-1,42,null,295235485820444,false,[[4,55],[5,[0,0]],[0,[20,8,43,false,null]],[0,[4,[5,[20,8,44,false,null],[6,[0,2],[7,[20,8,45,false,null],[0,180]]]],[0,2]]]]],[55,20,"Pin",471071539364119,false,[[4,8],[3,0]]],[55,22,null,968420436962609,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getWordByIndex("],[19,41]],[2,")"]]]]]]],[55,46,null,792928507425715,false,[[0,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getFontSizeByIndex("],[19,41]],[2,", 36)"]]]]]]]],[[0,null,false,null,821773047032803,[[-1,47,null,0,false,false,false,778360583751397,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.isBlankIndex("],[19,41]],[2,")"]]]]],[8,0],[7,[0,1]]]]],[[8,36,null,976608014020883,false,[[10,5],[7,[0,1]]]],[8,36,null,504979964690159,false,[[10,0],[7,[2,""]]]],[8,37,null,627993368489757,false,[[0,[0,1]]]],[55,22,null,848383151260631,false,[[7,[2,""]]]]]],[0,null,false,null,899485495625941,[[-1,48,null,0,false,false,false,316429817545316,false],[8,49,null,0,false,false,false,262001114515685,false,[[10,4],[8,0],[7,[0,1]]]]],[[8,36,null,300609304650323,false,[[10,5],[7,[0,0]]]],[8,36,null,809891674909458,false,[[10,0],[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getCorrectWordByIndex("],[19,41]],[2,")"]]]]]]],[55,22,null,952552231030407,false,[[7,[21,8,true,null,0]]]]]]]]]],[0,null,false,null,697646448924215,[[5,14,null,2,false,false,false,683656363419384,false,[[1,[2,"nextQuestion"]]]]],[[6,19,null,433354874189416,false,[[1,[2,"tdv_sdk.nextQuestion();"]]]],[5,28,null,840290663693184,false,[[1,[2,"loadQuestion"]],[13]]]]],[0,null,false,null,907166660008906,[[5,14,null,2,false,false,false,450652227133174,false,[[1,[2,"next"]]]]],[],[[0,null,false,null,369983601907982,[[-1,26,null,0,false,false,false,532208600232442,false,[[5,[2,"popup"]]]]],[[-1,18,null,605988914695713,false,[[5,[2,"popup"]],[3,0]]]],[[0,null,false,null,611507693831507,[[-1,47,null,0,false,false,false,235292780302559,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getCurrentNumber()"]]]],[8,5],[7,[20,6,23,false,null,[[2,"tdv_sdk.getTotalQuestions()"]]]]]]],[[6,19,null,670214247964547,false,[[1,[2,"tdv_sdk.result();"]]]],[-1,21,null,947787251251962,false,[[0,[0,1]]]],[-1,32,null,888716147069562,false,[[6,"Result"]]]]],[0,null,false,null,786993133130190,[[-1,48,null,0,false,false,false,387829253456711,false]],[[-1,34,null,665422350260877,false,[[11,"wordsPlaced"],[7,[0,0]]]],[-1,34,null,482914604361064,false,[[11,"userSentence"],[7,[2,""]]]],[6,19,null,200295095054716,false,[[1,[2,"tdv_sdk.nextQuestion();"]]]],[5,28,null,736937932703758,false,[[1,[2,"loadQuestion"]],[13]]]]]]]]],[0,null,false,null,885232395664091,[[3,50,"DragDrop",1,false,false,false,462077248880784,false]],[[14,25,null,400234397175915,false,[[2,["click",false]],[3,0],[0,[0,0]],[1,[2,""]]]],[3,51,null,397403794429243,false]],[[0,null,false,null,715788682150145,[[-1,47,null,0,false,false,false,975555513158536,false,[[7,[21,3,false,null,6]],[8,5],[7,[0,0]]]]],[[6,19,null,909569432999024,false,[[1,[10,[10,[2,"tdv_sdk.clearLetterAtSlot("],[21,3,false,null,6]],[2,")"]]]]],[3,36,null,363961653226411,false,[[10,6],[7,[0,-1]]]],[3,35,null,904620901742824,false,[[10,0],[3,0]]]]],[0,null,false,null,535992857419921,[[3,52,null,0,false,false,false,177353221158730,false,[[4,55]]]],[[55,53,null,334953306997069,false]]]]],[1,"placeResult",0,0,false,false,150551051042293,false],[0,null,false,null,876456068332522,[[3,54,"DragDrop",1,false,false,false,792974910922911,false]],[],[[0,null,false,null,962248118287846,[[3,52,null,0,false,false,false,124677826324657,false,[[4,8]]],[3,55,null,0,false,true,false,213672349331262,false,[[10,0]]],[8,49,null,0,false,false,false,852890087723952,false,[[10,5],[8,0],[7,[0,1]]]]],[[-1,34,null,325604451019262,false,[[11,"placeResult"],[7,[0,0]]]],[-1,34,null,906166679679094,false,[[11,"placeResult"],[7,[20,6,23,false,null,[[10,[10,[10,[10,[2,"tdv_sdk.setWordAtSlot('"],[21,3,true,null,5]],[2,"', "]],[21,8,false,null,3]],[2,")"]]]]]]]],[[0,null,false,null,512507223560049,[[-1,47,null,0,false,false,false,175458247629307,false,[[7,[23,"placeResult"]],[8,0],[7,[0,1]]]]],[[6,19,null,705465375236567,false,[[1,[10,[10,[10,[10,[2,"tdv_sdk.logPlacedWord('"],[21,3,true,null,5]],[2,"', "]],[23,"wordsPlaced"]],[2,")"]]]]],[3,56,null,464777312492432,false,[[0,[20,8,43,false,null]],[0,[20,8,44,false,null]]]],[8,35,null,931590115213927,false,[[10,2],[3,1]]],[8,36,null,756435568949718,false,[[10,0],[7,[21,3,true,null,5]]]],[3,35,null,654690834203345,false,[[10,0],[3,1]]],[3,36,null,191216822223520,false,[[10,6],[7,[21,8,false,null,3]]]]]],[0,null,false,null,355486164429369,[[-1,48,null,0,false,false,false,557592477148098,false]],[[3,57,"MoveTo",585878831288169,false,[[0,[21,3,false,null,7]],[0,[21,3,false,null,8]]]],[3,35,null,151862272533632,false,[[10,0],[3,0]]]]]]],[0,null,false,null,480243149569390,[[-1,48,null,0,false,false,false,406723678071445,false]],[[3,57,"MoveTo",991509780314297,false,[[0,[21,3,false,null,7]],[0,[21,3,false,null,8]]]],[3,35,null,618455789425416,false,[[10,0],[3,0]]]]]]],[0,null,false,null,675857356740891,[[-1,58,null,0,false,false,false,370244224606184,false,[[0,[1,1]]]],[-1,59,null,0,false,false,false,814249873798323,false,[[11,"gameState"],[8,0],[7,[2,"playing"]]]]],[[-1,34,null,852486726740550,false,[[11,"timer"],[7,[20,6,23,false,null,[[2,"tdv_sdk.getRemainingTime()"]]]]]],[56,22,null,219368848871802,false,[[7,[23,"timer"]]]]],[[0,null,false,null,685358610852170,[[-1,59,null,0,false,false,false,693623216783758,false,[[11,"timer"],[8,3],[7,[0,0]]]]],[[6,19,null,247938732318052,false,[[1,[2,"tdv_sdk.forceFinishGame();"]]]],[-1,32,null,985337743414200,false,[[6,"Result"]]]]]]],[0,null,false,null,236846276546805,[[-1,60,null,0,false,false,false,156545375284247,false]],[[57,22,null,209693118582684,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getCurrentScore()"]]]]]]]],[0,null,false,null,734897435823712,[[-1,60,null,0,false,false,false,560653658280359,false]],[],[[0,null,false,null,120933597520858,[[-1,47,null,0,false,false,false,752008358566402,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.canSubmitAnswer()"]]]],[8,0],[7,[0,1]]]]],[[9,17,null,218187814697551,false,[[3,1]]]]],[0,null,false,null,176434330825700,[[-1,48,null,0,false,false,false,868402124729995,false]],[[9,17,null,319260197635056,false,[[3,0]]]]]]],[0,null,false,null,198124435181627,[[4,61,null,1,false,false,false,968471510222435,false,[[4,9]]],[9,62,null,0,false,false,false,449456391350287,false]],[[-1,34,null,896282422945077,false,[[11,"result"],[7,[20,6,23,false,null,[[2,"tdv_sdk.submitAnswer()"]]]]]],[-1,18,null,487885391250917,false,[[5,[2,"popup"]],[3,1]]]],[[0,null,false,null,471424543889095,[[-1,59,null,0,false,false,false,558863681475477,false,[[11,"result"],[8,0],[7,[0,1]]]]],[[14,25,null,198862128495052,false,[[2,["correct",false]],[3,0],[0,[0,0]],[1,[2,""]]]],[-1,42,null,869008771903979,false,[[4,59],[5,[2,"Layer 0"]],[0,[20,9,43,false,null]],[0,[20,9,44,false,null]]]]]],[0,null,false,null,206534046243496,[[-1,59,null,0,false,false,false,564128024109930,false,[[11,"result"],[8,0],[7,[0,0]]]]],[[14,25,null,751178453895606,false,[[2,["fail",false]],[3,0],[0,[0,0]],[1,[2,""]]]],[-1,42,null,832971966522327,false,[[4,58],[5,[2,"Layer 0"]],[0,[20,9,43,false,null]],[0,[20,9,44,false,null]]]]]],[0,null,false,null,425803615709517,[[-1,63,null,0,false,false,false,264157804494786,false]],[[-1,21,null,230763842681626,false,[[0,[0,1]]]],[5,28,null,741482838148727,false,[[1,[2,"next"]],[13]]]]]]]]],["Result",[[0,null,false,null,869402415166568,[[-1,16,null,1,false,false,false,525095549732418,false]],[[6,19,null,607251342449872,false,[[1,[2,"tdv_sdk.leaderboard();"]]]],[-1,18,null,464292960825456,false,[[5,[2,"Leaderboard"]],[3,0]]],[38,64,null,626136405714026,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getCurrentScore()"]]]]]],[10,64,null,832434783984253,false,[[7,[23,"score"]]]],[35,64,null,100280010044226,false,[[7,[23,"bonus"]]]],[34,64,null,954973489793376,false,[[7,[4,[23,"score"],[23,"bonus"]]]]],[40,64,null,328225903739603,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getCorrectResultText()"]]]]]],[45,20,"Pin",541594237905073,false,[[4,50],[3,0]]],[49,20,"Pin",259112178443995,false,[[4,50],[3,0]]],[54,20,"Pin",531229209226329,false,[[4,50],[3,0]]],[61,20,"Pin",571550677471805,false,[[4,0],[3,0]]],[34,20,"Pin",545514430496319,false,[[4,0],[3,0]]],[35,20,"Pin",903779220227118,false,[[4,0],[3,0]]],[38,20,"Pin",933605395369996,false,[[4,0],[3,0]]],[39,20,"Pin",956499497490872,false,[[4,0],[3,0]]],[40,20,"Pin",346043886613784,false,[[4,0],[3,0]]],[51,20,"Pin",961059484131023,false,[[4,0],[3,0]]],[47,20,"Pin",204339450853292,false,[[4,46],[3,0]]],[50,20,"Pin",870117364717772,false,[[4,46],[3,0]]],[0,65,"MoveTo",533701982256744,false,[[0,[20,0,43,false,null]],[0,[0,-2000]]]],[46,65,"MoveTo",334574782779332,false,[[0,[20,46,43,false,null]],[0,[0,59]]]],[0,57,"MoveTo",362670796183920,false,[[0,[20,0,43,false,null]],[0,[1,628.5]]]]]],[0,null,false,null,352675978077684,[[4,61,null,1,false,false,false,239184189029640,false,[[4,51]]]],[[0,65,"MoveTo",461509406941708,false,[[0,[20,0,43,false,null]],[0,[0,-2000]]]],[-1,18,null,434953604539080,false,[[5,[2,"Layer 0"]],[3,0]]],[-1,18,null,196867115977817,false,[[5,[2,"Leaderboard"]],[3,1]]],[5,28,null,652173892454005,false,[[1,[2,"OnLeaderboardLoaded"]],[13]]],[-1,21,null,506761265453078,false,[[0,[0,1]]]]]],[0,null,false,null,420309984489462,[[4,61,null,1,false,false,false,273581270866045,false,[[4,47]]],[47,62,null,0,false,false,false,447083647042554,false]],[[-1,18,null,562908582277625,false,[[5,[2,"Leaderboard"]],[3,0]]],[-1,18,null,892818016093398,false,[[5,[2,"Layer 0"]],[3,1]]],[46,65,"MoveTo",722620590374056,false,[[0,[20,46,43,false,null]],[0,[0,-2000]]]],[0,57,"MoveTo",453291380950075,false,[[0,[20,0,43,false,null]],[0,[1,628.5]]]]]],[0,null,false,null,110032191370888,[[5,14,null,2,false,false,false,947895471222842,false,[[1,[2,"OnLeaderboardLoaded"]]]]],[[45,22,null,341968802763333,false,[[7,[10,[2,"Hạng của bạn: "],[20,6,23,false,null,[[2,"tdv_sdk.getLbUserAttr('rank')"]]]]]]],[49,22,null,376706767941042,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getLbUserAttr('score')"]]]]]],[54,22,null,542615012673879,false,[[7,[20,6,23,false,null,[[2,"tdv_sdk.getLbUserAttr('time_spent')"]]]]]]],[[0,null,false,null,470014039358122,[[-1,59,null,0,false,false,false,121139358136948,false,[[11,"isDoneLeaderBoard"],[8,0],[7,[0,0]]]]],[[42,39,null,242294023434745,false],[41,39,null,833806688438269,false],[48,38,null,436805153793148,false],[43,39,null,197024419602057,false],[52,38,null,828683313854133,false]]],[0,null,false,null,983947303706750,[[-1,48,null,0,false,false,false,957832558088220,false]],[]],[0,null,false,null,324796205380003,[[-1,66,null,0,true,false,false,981354505276881,false,[[1,[2,"i"]],[0,[0,0]],[0,[20,6,23,false,null,[[2,"tdv_sdk.getLbLength() - 1"]]]]]]],[],[[0,null,false,null,584350254279705,[[-1,59,null,0,false,false,false,670137131324563,false,[[11,"isDoneLeaderBoard"],[8,0],[7,[0,0]]]]],[[-1,42,null,986271973613063,false,[[4,48],[5,[2,"Leaderboard"]],[0,[0,600]],[0,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getLbItemY("],[19,41,[[2,"i"]]]],[2,", -100, 90)"]]]]]]],[-1,42,null,174923284311791,false,[[4,42],[5,[2,"Leaderboard"]],[0,[5,[20,48,43,false,null],[0,30]]],[0,[20,48,44,false,null]]]],[-1,42,null,628147996645621,false,[[4,41],[5,[2,"Leaderboard"]],[0,[4,[20,48,43,false,null],[0,200]]],[0,[20,48,44,false,null]]]],[-1,42,null,204218853106387,false,[[4,43],[5,[2,"Leaderboard"]],[0,[4,[20,48,43,false,null],[0,300]]],[0,[20,48,44,false,null]]]],[-1,42,null,548558623684350,false,[[4,52],[5,[2,"Leaderboard"]],[0,[5,[20,48,43,false,null],[0,300]]],[0,[5,[20,48,44,false,null],[0,5]]]]],[48,37,null,955332608430949,false,[[0,[19,41]]]],[52,37,null,134406708223083,false,[[0,[19,41]]]],[42,22,null,974108238231062,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getLbAttr("],[19,41,[[2,"i"]]]],[2,", 'name')"]]]]]]],[41,22,null,402225908104152,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getLbAttr("],[19,41,[[2,"i"]]]],[2,", 'score')"]]]]]]],[43,22,null,107596841223307,false,[[7,[20,6,23,false,null,[[10,[10,[2,"tdv_sdk.getLbAttr("],[19,41,[[2,"i"]]]],[2,", 'time_spent')"]]]]]]],[42,20,"Pin",762972739433523,false,[[4,46],[3,0]]],[41,20,"Pin",870232225771102,false,[[4,46],[3,0]]],[48,20,"Pin",777165397833028,false,[[4,46],[3,0]]],[43,20,"Pin",494025193779395,false,[[4,48],[3,0]]],[52,20,"Pin",926613930167230,false,[[4,48],[3,0]]]]],[0,null,false,null,496761973443300,[[-1,48,null,0,false,false,false,668026321288014,false]],[]]]],[0,null,false,null,452052322627635,[[-1,63,null,0,false,false,false,160521251751631,false]],[[46,57,"MoveTo",635784877856849,false,[[0,[20,46,43,false,null]],[0,[0,529]]]],[-1,34,null,641359852040355,false,[[11,"isDoneLeaderBoard"],[7,[0,1]]]]]]]],[1,"isDoneLeaderBoard",0,0,false,false,168399199294750,false]]]],[["bg.m4a",658130],["bg.ogg",594740],["click.m4a",2444],["click.ogg",5621],["correct.m4a",10198],["correct.ogg",12421],["fail.m4a",29104],["fail.ogg",24343]],"media/",false,1200,1200,3,true,true,true,"1.0.0.0",true,false,3,0,69,false,true,1,true,"G102-sequence",0,[]]}
\ No newline at end of file
diff --git a/G102-sequence/images/answers-sheet0.png b/G102-sequence/images/answers-sheet0.png
deleted file mode 100644
index c21085b..0000000
Binary files a/G102-sequence/images/answers-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/ao_vang_quan_xanh-sheet0.png b/G102-sequence/images/ao_vang_quan_xanh-sheet0.png
deleted file mode 100644
index ccba0a6..0000000
Binary files a/G102-sequence/images/ao_vang_quan_xanh-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/asset3-sheet0.png b/G102-sequence/images/asset3-sheet0.png
deleted file mode 100644
index 88f772f..0000000
Binary files a/G102-sequence/images/asset3-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/asset3-sheet1.png b/G102-sequence/images/asset3-sheet1.png
deleted file mode 100644
index faccc73..0000000
Binary files a/G102-sequence/images/asset3-sheet1.png and /dev/null differ
diff --git a/G102-sequence/images/avatar-sheet0.png b/G102-sequence/images/avatar-sheet0.png
deleted file mode 100644
index b6a5dda..0000000
Binary files a/G102-sequence/images/avatar-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/bg-sheet0.png b/G102-sequence/images/bg-sheet0.png
deleted file mode 100644
index 16015c4..0000000
Binary files a/G102-sequence/images/bg-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/btn_next-sheet0.png b/G102-sequence/images/btn_next-sheet0.png
deleted file mode 100644
index feee855..0000000
Binary files a/G102-sequence/images/btn_next-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/btn_play-sheet0.png b/G102-sequence/images/btn_play-sheet0.png
deleted file mode 100644
index 025297c..0000000
Binary files a/G102-sequence/images/btn_play-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/btn_play-sheet1.png b/G102-sequence/images/btn_play-sheet1.png
deleted file mode 100644
index 84a6275..0000000
Binary files a/G102-sequence/images/btn_play-sheet1.png and /dev/null differ
diff --git a/G102-sequence/images/btn_submit-sheet0.png b/G102-sequence/images/btn_submit-sheet0.png
deleted file mode 100644
index f0397aa..0000000
Binary files a/G102-sequence/images/btn_submit-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/btn_submit2-sheet0.png b/G102-sequence/images/btn_submit2-sheet0.png
deleted file mode 100644
index 5a866fa..0000000
Binary files a/G102-sequence/images/btn_submit2-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/checker_frame-sheet0.png b/G102-sequence/images/checker_frame-sheet0.png
deleted file mode 100644
index 2311d13..0000000
Binary files a/G102-sequence/images/checker_frame-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/coin-sheet0.png b/G102-sequence/images/coin-sheet0.png
deleted file mode 100644
index 8aa8618..0000000
Binary files a/G102-sequence/images/coin-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/dong_ho-sheet0.png b/G102-sequence/images/dong_ho-sheet0.png
deleted file mode 100644
index 99b8317..0000000
Binary files a/G102-sequence/images/dong_ho-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/frame_door-sheet0.png b/G102-sequence/images/frame_door-sheet0.png
deleted file mode 100644
index 35736b0..0000000
Binary files a/G102-sequence/images/frame_door-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/frame_door_left-sheet0.png b/G102-sequence/images/frame_door_left-sheet0.png
deleted file mode 100644
index c84d188..0000000
Binary files a/G102-sequence/images/frame_door_left-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/frame_door_right-sheet0.png b/G102-sequence/images/frame_door_right-sheet0.png
deleted file mode 100644
index bb12eec..0000000
Binary files a/G102-sequence/images/frame_door_right-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/frame_score-sheet0.png b/G102-sequence/images/frame_score-sheet0.png
deleted file mode 100644
index 9064d47..0000000
Binary files a/G102-sequence/images/frame_score-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/hand_left-sheet0.png b/G102-sequence/images/hand_left-sheet0.png
deleted file mode 100644
index c9606b7..0000000
Binary files a/G102-sequence/images/hand_left-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/hand_right-sheet0.png b/G102-sequence/images/hand_right-sheet0.png
deleted file mode 100644
index 24c4ec8..0000000
Binary files a/G102-sequence/images/hand_right-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/human-sheet0.png b/G102-sequence/images/human-sheet0.png
deleted file mode 100644
index 492d121..0000000
Binary files a/G102-sequence/images/human-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/khung_diem-sheet0.png b/G102-sequence/images/khung_diem-sheet0.png
deleted file mode 100644
index f7678f9..0000000
Binary files a/G102-sequence/images/khung_diem-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/khung_thoai-sheet0.png b/G102-sequence/images/khung_thoai-sheet0.png
deleted file mode 100644
index 5bd7fc6..0000000
Binary files a/G102-sequence/images/khung_thoai-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/khung_thoai2-sheet0.png b/G102-sequence/images/khung_thoai2-sheet0.png
deleted file mode 100644
index f5b79dc..0000000
Binary files a/G102-sequence/images/khung_thoai2-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_btn_exit-sheet0.png b/G102-sequence/images/sena_btn_exit-sheet0.png
deleted file mode 100644
index 4489a16..0000000
Binary files a/G102-sequence/images/sena_btn_exit-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_btn_leaderboard-sheet0.png b/G102-sequence/images/sena_btn_leaderboard-sheet0.png
deleted file mode 100644
index d99c749..0000000
Binary files a/G102-sequence/images/sena_btn_leaderboard-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_btn_replay-sheet0.png b/G102-sequence/images/sena_btn_replay-sheet0.png
deleted file mode 100644
index 2767a71..0000000
Binary files a/G102-sequence/images/sena_btn_replay-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_fx_correct_mark-sheet0.png b/G102-sequence/images/sena_fx_correct_mark-sheet0.png
deleted file mode 100644
index acfca94..0000000
Binary files a/G102-sequence/images/sena_fx_correct_mark-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_fx_wrong_mark-sheet0.png b/G102-sequence/images/sena_fx_wrong_mark-sheet0.png
deleted file mode 100644
index b6a9daa..0000000
Binary files a/G102-sequence/images/sena_fx_wrong_mark-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_title_leaderboard-sheet0.png b/G102-sequence/images/sena_title_leaderboard-sheet0.png
deleted file mode 100644
index 537448f..0000000
Binary files a/G102-sequence/images/sena_title_leaderboard-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_frame_intro-sheet0.png b/G102-sequence/images/sena_ui_frame_intro-sheet0.png
deleted file mode 100644
index d2c74de..0000000
Binary files a/G102-sequence/images/sena_ui_frame_intro-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_frame_leaderboard-sheet0.png b/G102-sequence/images/sena_ui_frame_leaderboard-sheet0.png
deleted file mode 100644
index 69f2207..0000000
Binary files a/G102-sequence/images/sena_ui_frame_leaderboard-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_frame_result-sheet0.png b/G102-sequence/images/sena_ui_frame_result-sheet0.png
deleted file mode 100644
index 1cde514..0000000
Binary files a/G102-sequence/images/sena_ui_frame_result-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_item_bg-sheet0.png b/G102-sequence/images/sena_ui_item_bg-sheet0.png
deleted file mode 100644
index dfed4df..0000000
Binary files a/G102-sequence/images/sena_ui_item_bg-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_item_bg_user_rank-sheet0.png b/G102-sequence/images/sena_ui_item_bg_user_rank-sheet0.png
deleted file mode 100644
index de3aaa4..0000000
Binary files a/G102-sequence/images/sena_ui_item_bg_user_rank-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_number_rank-sheet0.png b/G102-sequence/images/sena_ui_number_rank-sheet0.png
deleted file mode 100644
index 8f2019a..0000000
Binary files a/G102-sequence/images/sena_ui_number_rank-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_number_rank-sheet1.png b/G102-sequence/images/sena_ui_number_rank-sheet1.png
deleted file mode 100644
index ff6fcec..0000000
Binary files a/G102-sequence/images/sena_ui_number_rank-sheet1.png and /dev/null differ
diff --git a/G102-sequence/images/sena_ui_number_rank-sheet2.png b/G102-sequence/images/sena_ui_number_rank-sheet2.png
deleted file mode 100644
index 2e9e71b..0000000
Binary files a/G102-sequence/images/sena_ui_number_rank-sheet2.png and /dev/null differ
diff --git a/G102-sequence/images/sprite-sheet0.png b/G102-sequence/images/sprite-sheet0.png
deleted file mode 100644
index 4f5f653..0000000
Binary files a/G102-sequence/images/sprite-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/star_-sheet0.png b/G102-sequence/images/star_-sheet0.png
deleted file mode 100644
index 8748a3d..0000000
Binary files a/G102-sequence/images/star_-sheet0.png and /dev/null differ
diff --git a/G102-sequence/images/txt_answerss.png b/G102-sequence/images/txt_answerss.png
deleted file mode 100644
index c4f063d..0000000
Binary files a/G102-sequence/images/txt_answerss.png and /dev/null differ
diff --git a/G102-sequence/images/txt_instructions.png b/G102-sequence/images/txt_instructions.png
deleted file mode 100644
index fefb49d..0000000
Binary files a/G102-sequence/images/txt_instructions.png and /dev/null differ
diff --git a/G102-sequence/index.html b/G102-sequence/index.html
deleted file mode 100644
index 8a8b894..0000000
--- a/G102-sequence/index.html
+++ /dev/null
@@ -1,235 +0,0 @@
-
-
-
-
-
- G102-sequence
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/G102-sequence/media/bg.m4a b/G102-sequence/media/bg.m4a
deleted file mode 100644
index 5f816a1..0000000
Binary files a/G102-sequence/media/bg.m4a and /dev/null differ
diff --git a/G102-sequence/media/bg.ogg b/G102-sequence/media/bg.ogg
deleted file mode 100644
index ff861a0..0000000
Binary files a/G102-sequence/media/bg.ogg and /dev/null differ
diff --git a/G102-sequence/media/click.m4a b/G102-sequence/media/click.m4a
deleted file mode 100644
index 8874ebe..0000000
Binary files a/G102-sequence/media/click.m4a and /dev/null differ
diff --git a/G102-sequence/media/click.ogg b/G102-sequence/media/click.ogg
deleted file mode 100644
index 715aabf..0000000
Binary files a/G102-sequence/media/click.ogg and /dev/null differ
diff --git a/G102-sequence/media/correct.m4a b/G102-sequence/media/correct.m4a
deleted file mode 100644
index e796026..0000000
Binary files a/G102-sequence/media/correct.m4a and /dev/null differ
diff --git a/G102-sequence/media/correct.ogg b/G102-sequence/media/correct.ogg
deleted file mode 100644
index 0d86e4f..0000000
Binary files a/G102-sequence/media/correct.ogg and /dev/null differ
diff --git a/G102-sequence/media/fail.m4a b/G102-sequence/media/fail.m4a
deleted file mode 100644
index eb8f31f..0000000
Binary files a/G102-sequence/media/fail.m4a and /dev/null differ
diff --git a/G102-sequence/media/fail.ogg b/G102-sequence/media/fail.ogg
deleted file mode 100644
index 2a4f445..0000000
Binary files a/G102-sequence/media/fail.ogg and /dev/null differ
diff --git a/G102-sequence/offline.js b/G102-sequence/offline.js
deleted file mode 100644
index 3be2527..0000000
--- a/G102-sequence/offline.js
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "version": 1769236279,
- "fileList": [
- "data.js",
- "c2runtime.js",
- "jquery-3.4.1.min.js",
- "offlineClient.js",
- "images/sena_ui_frame_result-sheet0.png",
- "images/sena_btn_replay-sheet0.png",
- "images/asset3-sheet0.png",
- "images/asset3-sheet1.png",
- "images/answers-sheet0.png",
- "images/txt_answerss.png",
- "images/checker_frame-sheet0.png",
- "images/btn_submit-sheet0.png",
- "images/txt_instructions.png",
- "images/btn_submit2-sheet0.png",
- "images/btn_next-sheet0.png",
- "images/btn_play-sheet0.png",
- "images/btn_play-sheet1.png",
- "images/bg-sheet0.png",
- "images/frame_door-sheet0.png",
- "images/frame_door_left-sheet0.png",
- "images/frame_door_right-sheet0.png",
- "images/hand_right-sheet0.png",
- "images/hand_left-sheet0.png",
- "images/ao_vang_quan_xanh-sheet0.png",
- "images/sprite-sheet0.png",
- "images/khung_thoai-sheet0.png",
- "images/khung_thoai2-sheet0.png",
- "images/khung_diem-sheet0.png",
- "images/avatar-sheet0.png",
- "images/star_-sheet0.png",
- "images/frame_score-sheet0.png",
- "images/dong_ho-sheet0.png",
- "images/coin-sheet0.png",
- "images/sena_ui_frame_intro-sheet0.png",
- "images/sena_title_leaderboard-sheet0.png",
- "images/sena_ui_frame_leaderboard-sheet0.png",
- "images/sena_btn_exit-sheet0.png",
- "images/sena_ui_item_bg-sheet0.png",
- "images/sena_ui_item_bg_user_rank-sheet0.png",
- "images/sena_btn_leaderboard-sheet0.png",
- "images/sena_ui_number_rank-sheet0.png",
- "images/sena_ui_number_rank-sheet1.png",
- "images/sena_ui_number_rank-sheet2.png",
- "images/sena_fx_wrong_mark-sheet0.png",
- "images/sena_fx_correct_mark-sheet0.png",
- "media/bg.m4a",
- "media/bg.ogg",
- "media/click.m4a",
- "media/click.ogg",
- "media/correct.m4a",
- "media/correct.ogg",
- "media/fail.m4a",
- "media/fail.ogg",
- "icon-16.png",
- "icon-32.png",
- "icon-114.png",
- "icon-128.png",
- "icon-256.png",
- "loading-logo.png",
- "tdv_sdk.js",
- "bg.mp4"
- ]
-}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/README.md b/G102-sequence/sdk/package/README.md
deleted file mode 100644
index 5488234..0000000
--- a/G102-sequence/sdk/package/README.md
+++ /dev/null
@@ -1,506 +0,0 @@
-# SDK Message Protocol
-
-Game giao tiếp với SDK thông qua **postMessage** trong hidden iframe. Game chỉ cần biết các message types, payloads, và khi nào gửi/nhận.
-
----
-
-## 🔌 Architecture
-
-```
-┌──────────────────────────────┐
-│ Game (React/Vue/etc) │
-│ │
-│ window.parent.postMessage() │
-│ window.addEventListener() │
-└──────────────┬───────────────┘
- │ postMessage
- │ (JSON)
- ↓
- ┌──────────────────────┐
- │ Hidden Iframe │
- │ (sdk-iframe.html) │
- │ │
- │ - Sanitize data │
- │ - Verify answers │
- │ - Call API │
- │ - Send responses │
- └──────────────────────┘
-```
-
----
-
-## 📨 Message Types
-
-### 1️⃣ **SDK_INIT** (Game → SDK)
-
-Game khởi tạo SDK với mode và game_code.
-
-**Gửi:**
-```javascript
-window.parent.postMessage({
- type: 'SDK_INIT',
- payload: {
- mode: 'dev' | 'preview' | 'live',
- game_code: 'G001' | 'G002' | ... | 'G123',
-
- // LIVE mode only:
- assignment_id?: string,
- student_id?: string,
- api_base_url?: string,
- auth_token?: string
- }
-}, '*');
-```
-
-**Ví dụ DEV mode:**
-```javascript
-window.parent.postMessage({
- type: 'SDK_INIT',
- payload: {
- mode: 'dev',
- game_code: 'G001'
- }
-}, '*');
-```
-
-**Ví dụ LIVE mode:**
-```javascript
-window.parent.postMessage({
- type: 'SDK_INIT',
- payload: {
- mode: 'live',
- game_code: 'G001',
- assignment_id: 'ASSIGN_123',
- student_id: 'STU_456',
- api_base_url: 'https://api.sena.tech',
- auth_token: 'token_xyz'
- }
-}, '*');
-```
-
-**Nhận (SDK gửi lại khi ready):**
-```javascript
-{
- type: 'SDK_READY',
- payload: {
- mode: 'dev' | 'preview' | 'live',
- game_code: 'G001'
- }
-}
-```
-
----
-
-### 2️⃣ **SDK_DATA_READY** (SDK → Game)
-
-SDK gửi sanitized data cho game render. Game phải listen sự kiện này.
-
-**Nhận:**
-```javascript
-window.addEventListener('message', (event) => {
- if (event.data.type === 'SDK_DATA_READY') {
- const {
- items, // Sanitized items (NO answers!)
- total_questions,
- completed_count,
- resume_data // Optional: previous results
- } = event.data.payload;
-
- // Render game
- renderGame(items);
- }
-});
-```
-
-**Payload items (tùy game_code):**
-
-#### Quiz Games (G001-G004):
-```json
-{
- "id": "q1",
- "question": "What is 2+2?",
- "options": [
- {"text": "5"},
- {"text": "4"},
- {"text": "3"}
- ]
-}
-```
-
-#### Sequence Games (G110-G123):
-```json
-{
- "id": "seq1",
- "question": ["H", "", "L", "", "O"],
- "options": ["L", "E"],
- "audio_url": "https://..." // optional
-}
-```
-
----
-
-### 3️⃣ **SDK_CHECK_ANSWER** (Game → SDK)
-
-Game gửi user's answer để SDK verify.
-
-**Gửi:**
-```javascript
-window.parent.postMessage({
- type: 'SDK_CHECK_ANSWER',
- payload: {
- question_id: 'q1',
- choice: any, // Index (quiz) hoặc Array (sequence)
- time_spent?: number // Milliseconds
- }
-}, '*');
-```
-
-**Quiz example (choice = index):**
-```javascript
-window.parent.postMessage({
- type: 'SDK_CHECK_ANSWER',
- payload: {
- question_id: 'q1',
- choice: 1, // User clicked option index 1
- time_spent: 5000
- }
-}, '*');
-```
-
-**Sequence example (choice = reordered array):**
-```javascript
-window.parent.postMessage({
- type: 'SDK_CHECK_ANSWER',
- payload: {
- question_id: 'seq1',
- choice: ["H", "e", "l", "l", "o"], // Reordered
- time_spent: 8000
- }
-}, '*');
-```
-
----
-
-### 4️⃣ **SDK_ANSWER_RESULT** (SDK → Game)
-
-SDK gửi kết quả verify.
-
-**Nhận:**
-```javascript
-window.addEventListener('message', (event) => {
- if (event.data.type === 'SDK_ANSWER_RESULT') {
- const {
- question_id,
- correct, // true/false
- score, // 0-1 hoặc custom
- synced, // true = already synced to server
- feedback // Optional: "✅ Correct!" or "❌ Wrong"
- } = event.data.payload;
-
- if (correct) {
- showCorrectFeedback(question_id);
- } else {
- showWrongFeedback(question_id);
- }
- }
-});
-```
-
----
-
-### 5️⃣ **SDK_PUSH_DATA** (Game → SDK, PREVIEW only)
-
-Nếu PREVIEW mode, game có thể push data thay vì SDK fetch.
-
-**Gửi:**
-```javascript
-window.parent.postMessage({
- type: 'SDK_PUSH_DATA',
- payload: {
- items: [
- {
- id: 'q1',
- question: 'What is 2+2?',
- options: [
- {text: '3'},
- {text: '4'},
- {text: '5'}
- ],
- answer: '4' // Server data (with answer)
- },
- // ... more items
- ]
- }
-}, '*');
-```
-
-SDK sẽ sanitize (remove answer, shuffle options) rồi gửi SDK_DATA_READY.
-
----
-
-### 6️⃣ **SDK_ERROR** (SDK → Game)
-
-SDK gửi error notification.
-
-**Nhận:**
-```javascript
-window.addEventListener('message', (event) => {
- if (event.data.type === 'SDK_ERROR') {
- const {
- code, // Error code
- message, // Error message
- details // Optional: more info
- } = event.data.payload;
-
- console.error(`[SDK Error] ${code}: ${message}`);
- }
-});
-```
-
----
-
-## 🎮 Data Structures by Game Type
-
-### Quiz Games (G001-G004)
-
-#### Sanitized (Game receives):
-```json
-{
- "id": "q1",
- "question": "Audio URL or text",
- "image_url": "Image URL (optional)",
- "options": [
- {"text": "Option A"} or {"audio": "Audio URL"}
- ]
-}
-```
-
-#### User Answer Format:
-```javascript
-choice = 0 // Index of selected option
-```
-
----
-
-### Sequence Word (G110-G113)
-
-#### Sanitized (Game receives):
-```json
-{
- "id": "seq_word_1",
- "question": ["H", "", "L", "", "O"],
- "options": ["L", "E"],
- "audio_url": "URL (optional)"
-}
-```
-
-#### User Answer Format:
-```javascript
-choice = ["H", "e", "l", "l", "o"] // Reordered array
-```
-
----
-
-### Sequence Sentence (G120-G123)
-
-#### Sanitized (Game receives):
-```json
-{
- "id": "seq_sent_1",
- "question": ["I", "", "reading", ""],
- "options": ["love", "books"],
- "audio_url": "URL (optional)"
-}
-```
-
-#### User Answer Format:
-```javascript
-choice = ["I", "love", "reading", "books"] // Reordered
-```
-
----
-
-## 💻 Complete Game Implementation Example
-
-```javascript
-// ============ INITIALIZE ============
-
-// Listen for SDK messages
-window.addEventListener('message', (event) => {
- handleSdkMessage(event.data);
-});
-
-// Initialize SDK
-function initGame() {
- const mode = 'live';
- const gameCode = 'G001';
-
- window.parent.postMessage({
- type: 'SDK_INIT',
- payload: {
- mode,
- game_code: gameCode,
- assignment_id: 'ASSIGN_123',
- student_id: 'STU_456',
- api_base_url: 'https://api.sena.tech'
- }
- }, '*');
-}
-
-// Handle all SDK messages
-function handleSdkMessage(data) {
- switch (data.type) {
- case 'SDK_READY':
- console.log('SDK initialized:', data.payload);
- break;
-
- case 'SDK_DATA_READY':
- const items = data.payload.items;
- renderGameItems(items);
- break;
-
- case 'SDK_ANSWER_RESULT':
- const result = data.payload;
- if (result.correct) {
- showCorrectFeedback(result.question_id);
- } else {
- showWrongFeedback(result.question_id);
- }
- break;
-
- case 'SDK_ERROR':
- console.error('SDK Error:', data.payload);
- break;
- }
-}
-
-// ============ RENDER GAME ============
-
-function renderGameItems(items) {
- items.forEach(item => {
- if (item.options) {
- // Quiz game
- renderQuizQuestion(item);
- } else if (Array.isArray(item.question)) {
- // Sequence game
- renderSequenceGame(item);
- }
- });
-}
-
-// ============ HANDLE USER ANSWER ============
-
-function submitAnswer(questionId, userChoice) {
- window.parent.postMessage({
- type: 'SDK_CHECK_ANSWER',
- payload: {
- question_id: questionId,
- choice: userChoice, // Index for quiz, array for sequence
- time_spent: 5000
- }
- }, '*');
-}
-
-// ============ GAME START ============
-
-// Start when page loads
-window.addEventListener('load', () => {
- initGame();
-});
-```
-
----
-
-## 🔄 Message Flow Examples
-
-### DEV Mode (Local Verify)
-```
-Game: SDK_INIT
- ↓
-SDK: SDK_READY
- ↓
-SDK: SDK_DATA_READY (mock items)
- ↓
-Game: SDK_CHECK_ANSWER
- ↓
-SDK: SDK_ANSWER_RESULT (instantly)
-```
-
-### LIVE Mode (Server Verify)
-```
-Game: SDK_INIT
- ↓
-SDK: SDK_READY
- ↓
-SDK: fetch from API → SDK_DATA_READY
- ↓
-Game: SDK_CHECK_ANSWER
- ↓
-SDK: POST to server
- ↓
-SDK: SDK_ANSWER_RESULT (wait for server)
-```
-
-### PREVIEW Mode (Push Data)
-```
-Game: SDK_INIT (mode='preview')
- ↓
-SDK: SDK_READY
- ↓
-Game: SDK_PUSH_DATA (items with answers)
- ↓
-SDK: sanitize → SDK_DATA_READY
- ↓
-Game: SDK_CHECK_ANSWER
- ↓
-SDK: SDK_ANSWER_RESULT (local verify)
-```
-
----
-
-## ⚠️ Important Notes
-
-✅ **SDK Always Sanitizes**
-- Removes `answer` field
-- Removes `word`, `sentence`, `parts`, `missing_letter_count`
-- Shuffles options (for quiz)
-
-✅ **Game Never Gets Answer**
-- Game receives only question + options
-- Answer is stored server-side
-
-✅ **Shuffled Options**
-- Game receives shuffled options array
-- Game user clicks index
-- SDK internally resolves index → text
-
-✅ **Sequence Games**
-- Random positions are blanked (based on `missing_letter_count`)
-- Game receives question with blanks + missing items
-- User reorders missing items
-
----
-
-## 🚀 Testing
-
-Test locally without SDK:
-```javascript
-// Simulate SDK messages for testing
-function simulateSdkMessage(type, payload) {
- const event = new MessageEvent('message', {
- data: { type, payload }
- });
- window.dispatchEvent(event);
-}
-
-// Simulate SDK_DATA_READY
-simulateSdkMessage('SDK_DATA_READY', {
- items: [
- {
- id: 'q1',
- question: 'What is 2+2?',
- options: [{text: '4'}, {text: '5'}, {text: '3'}]
- }
- ]
-});
-```
diff --git a/G102-sequence/sdk/package/dist/EventEmitter.d.ts b/G102-sequence/sdk/package/dist/EventEmitter.d.ts
deleted file mode 100644
index 8a6f8a3..0000000
--- a/G102-sequence/sdk/package/dist/EventEmitter.d.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Game Iframe SDK - Event Emitter
- * Simple typed event emitter for SDK
- */
-export type EventHandler = (data: T) => void;
-export declare class EventEmitter> {
- private handlers;
- /**
- * Subscribe to an event
- */
- on(event: K, handler: EventHandler): () => void;
- /**
- * Subscribe to an event (once)
- */
- once(event: K, handler: EventHandler): () => void;
- /**
- * Unsubscribe from an event
- */
- off(event: K, handler: EventHandler): void;
- /**
- * Emit an event
- */
- emit(event: K, data: Events[K]): void;
- /**
- * Remove all handlers for an event (or all events)
- */
- removeAllListeners(event?: keyof Events): void;
-}
-//# sourceMappingURL=EventEmitter.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/EventEmitter.d.ts.map b/G102-sequence/sdk/package/dist/EventEmitter.d.ts.map
deleted file mode 100644
index bb5561d..0000000
--- a/G102-sequence/sdk/package/dist/EventEmitter.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../src/EventEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAEtD,qBAAa,YAAY,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACxD,OAAO,CAAC,QAAQ,CAAmD;IAEnE;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAUlF;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAQpF;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAI7E;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAU7D;;OAEG;IACH,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI;CAOjD"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/EventEmitter.js b/G102-sequence/sdk/package/dist/EventEmitter.js
deleted file mode 100644
index 72c9cdb..0000000
--- a/G102-sequence/sdk/package/dist/EventEmitter.js
+++ /dev/null
@@ -1,65 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Event Emitter
- * Simple typed event emitter for SDK
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.EventEmitter = void 0;
-class EventEmitter {
- constructor() {
- this.handlers = new Map();
- }
- /**
- * Subscribe to an event
- */
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- // Return unsubscribe function
- return () => this.off(event, handler);
- }
- /**
- * Subscribe to an event (once)
- */
- once(event, handler) {
- const wrappedHandler = (data) => {
- this.off(event, wrappedHandler);
- handler(data);
- };
- return this.on(event, wrappedHandler);
- }
- /**
- * Unsubscribe from an event
- */
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- /**
- * Emit an event
- */
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- console.error(`[EventEmitter] Error in handler for "${String(event)}":`, err);
- }
- });
- }
- /**
- * Remove all handlers for an event (or all events)
- */
- removeAllListeners(event) {
- if (event) {
- this.handlers.delete(event);
- }
- else {
- this.handlers.clear();
- }
- }
-}
-exports.EventEmitter = EventEmitter;
-//# sourceMappingURL=EventEmitter.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/EventEmitter.js.map b/G102-sequence/sdk/package/dist/EventEmitter.js.map
deleted file mode 100644
index 7d574fe..0000000
--- a/G102-sequence/sdk/package/dist/EventEmitter.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"EventEmitter.js","sourceRoot":"","sources":["../src/EventEmitter.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,MAAa,YAAY;IAAzB;QACY,aAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;IAwDvE,CAAC;IAtDG;;OAEG;IACH,EAAE,CAAyB,KAAQ,EAAE,OAAgC;QACjE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEvC,8BAA8B;QAC9B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,IAAI,CAAyB,KAAQ,EAAE,OAAgC;QACnE,MAAM,cAAc,GAAG,CAAC,IAAe,EAAE,EAAE;YACvC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,GAAG,CAAyB,KAAQ,EAAE,OAAgC;QAClE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAI,CAAyB,KAAQ,EAAE,IAAe;QAClD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;YACxC,IAAI,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,wCAAwC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAClF,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,KAAoB;QACnC,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACL,CAAC;CACJ;AAzDD,oCAyDC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts b/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts
deleted file mode 100644
index 7cec288..0000000
--- a/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Game Iframe SDK - Core
- * SDK chính - compose các layers: MessageHandler, MessageSender
- */
-import { EventEmitter } from './EventEmitter';
-import { MessageHandler } from './MessageHandler';
-import { MessageSender } from './MessageSender';
-import { GameIframeSDKConfig, SDKEvents, PushDataPayload, LeaderboardData } from './types';
-/**
- * GameIframeSDK - Main SDK class
- * Composes MessageHandler và MessageSender
- */
-export declare class GameIframeSDK extends EventEmitter {
- private config;
- private messageHandler;
- private messageSender;
- private pendingData;
- private isReady;
- constructor(config: GameIframeSDKConfig);
- /**
- * Set iframe element reference
- */
- setIframe(iframe: HTMLIFrameElement | null): this;
- /**
- * Get current iframe
- */
- getIframe(): HTMLIFrameElement | null;
- /**
- * Check if game is ready
- */
- isGameReady(): boolean;
- /**
- * Check if sender is ready (iframe available)
- */
- isSenderReady(): boolean;
- /**
- * Send game data to iframe
- */
- sendGameData(data: PushDataPayload): boolean;
- /**
- * Send leaderboard data to iframe
- */
- sendLeaderboard(data: LeaderboardData): boolean;
- /**
- * Queue data to be sent when game is ready
- */
- queueGameData(data: PushDataPayload): this;
- /**
- * Clear queued data
- */
- clearQueuedData(): this;
- /**
- * Force reload iframe
- */
- reloadIframe(): boolean;
- /**
- * Cleanup and destroy SDK
- */
- destroy(): void;
- /**
- * Get MessageHandler instance for advanced usage
- */
- getMessageHandler(): MessageHandler;
- /**
- * Get MessageSender instance for advanced usage
- */
- getMessageSender(): MessageSender;
- /**
- * Setup event forwarding from MessageHandler to SDK events
- */
- private setupEventForwarding;
- /**
- * Send queued data
- */
- private sendQueuedData;
- /**
- * Internal logging
- */
- private log;
-}
-/**
- * Create SDK instance
- */
-export declare function createGameIframeSDK(config: GameIframeSDKConfig): GameIframeSDK;
-/**
- * Get or create default SDK instance
- */
-export declare function getGameIframeSDK(config?: GameIframeSDKConfig): GameIframeSDK;
-/**
- * Destroy default instance
- */
-export declare function destroyGameIframeSDK(): void;
-//# sourceMappingURL=GameIframeSDK.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts.map b/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts.map
deleted file mode 100644
index 35f8e1a..0000000
--- a/G102-sequence/sdk/package/dist/GameIframeSDK.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameIframeSDK.d.ts","sourceRoot":"","sources":["../src/GameIframeSDK.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACH,mBAAmB,EAEnB,SAAS,EACT,eAAe,EACf,eAAe,EAClB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,SAAS,CAAC;IACtD,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,OAAO,CAAkB;gBAErB,MAAM,EAAE,mBAAmB;IA4BvC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAOjD;;OAEG;IACH,SAAS,IAAI,iBAAiB,GAAG,IAAI;IAIrC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,aAAa,IAAI,OAAO;IAQxB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO;IAa5C;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO;IAiB/C;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAY1C;;OAEG;IACH,eAAe,IAAI,IAAI;IASvB;;OAEG;IACH,YAAY,IAAI,OAAO;IASvB;;OAEG;IACH,OAAO,IAAI,IAAI;IAYf;;OAEG;IACH,iBAAiB,IAAI,cAAc;IAInC;;OAEG;IACH,gBAAgB,IAAI,aAAa;IAQjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmC5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,GAAG;CAkBd;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAE9E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAQ5E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/GameIframeSDK.js b/G102-sequence/sdk/package/dist/GameIframeSDK.js
deleted file mode 100644
index edf6fa1..0000000
--- a/G102-sequence/sdk/package/dist/GameIframeSDK.js
+++ /dev/null
@@ -1,254 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Core
- * SDK chính - compose các layers: MessageHandler, MessageSender
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GameIframeSDK = void 0;
-exports.createGameIframeSDK = createGameIframeSDK;
-exports.getGameIframeSDK = getGameIframeSDK;
-exports.destroyGameIframeSDK = destroyGameIframeSDK;
-const EventEmitter_1 = require("./EventEmitter");
-const MessageHandler_1 = require("./MessageHandler");
-const MessageSender_1 = require("./MessageSender");
-const types_1 = require("./types");
-/**
- * GameIframeSDK - Main SDK class
- * Composes MessageHandler và MessageSender
- */
-class GameIframeSDK extends EventEmitter_1.EventEmitter {
- constructor(config) {
- super();
- this.pendingData = null;
- this.isReady = false;
- this.config = { ...types_1.DEFAULT_CONFIG, ...config };
- // Initialize layers
- this.messageHandler = new MessageHandler_1.MessageHandler({
- acceptedOrigin: this.config.iframeOrigin,
- debug: this.config.debug,
- });
- this.messageSender = new MessageSender_1.MessageSender({
- targetOrigin: this.config.iframeOrigin,
- debug: this.config.debug,
- });
- // Setup event forwarding
- this.setupEventForwarding();
- // Start listening
- this.messageHandler.start();
- this.log('info', 'SDK initialized', { config: this.config });
- }
- // ==========================================================================
- // PUBLIC API - Iframe Management
- // ==========================================================================
- /**
- * Set iframe element reference
- */
- setIframe(iframe) {
- this.messageSender.setIframe(iframe);
- this.isReady = false;
- this.log('info', 'Iframe set', { hasIframe: !!iframe });
- return this;
- }
- /**
- * Get current iframe
- */
- getIframe() {
- return this.messageSender.getIframe();
- }
- /**
- * Check if game is ready
- */
- isGameReady() {
- return this.isReady;
- }
- /**
- * Check if sender is ready (iframe available)
- */
- isSenderReady() {
- return this.messageSender.isReady();
- }
- // ==========================================================================
- // PUBLIC API - Send Data
- // ==========================================================================
- /**
- * Send game data to iframe
- */
- sendGameData(data) {
- const result = this.messageSender.sendGameData(data);
- if (!result.success) {
- this.emit('error', {
- message: 'Failed to send game data',
- error: result.error,
- });
- }
- return result.success;
- }
- /**
- * Send leaderboard data to iframe
- */
- sendLeaderboard(data) {
- const result = this.messageSender.sendLeaderboard(data);
- if (!result.success) {
- this.emit('error', {
- message: 'Failed to send leaderboard',
- error: result.error,
- });
- }
- return result.success;
- }
- // ==========================================================================
- // PUBLIC API - Queue & Auto-send
- // ==========================================================================
- /**
- * Queue data to be sent when game is ready
- */
- queueGameData(data) {
- this.pendingData = data;
- this.log('info', 'Data queued for when game is ready');
- // If already ready, send immediately
- if (this.isReady) {
- this.sendQueuedData();
- }
- return this;
- }
- /**
- * Clear queued data
- */
- clearQueuedData() {
- this.pendingData = null;
- return this;
- }
- // ==========================================================================
- // PUBLIC API - Iframe Control
- // ==========================================================================
- /**
- * Force reload iframe
- */
- reloadIframe() {
- this.isReady = false;
- return this.messageSender.reloadIframe();
- }
- // ==========================================================================
- // PUBLIC API - Lifecycle
- // ==========================================================================
- /**
- * Cleanup and destroy SDK
- */
- destroy() {
- this.messageHandler.destroy();
- this.removeAllListeners();
- this.pendingData = null;
- this.isReady = false;
- this.log('info', 'SDK destroyed');
- }
- // ==========================================================================
- // PUBLIC API - Direct Layer Access (Advanced)
- // ==========================================================================
- /**
- * Get MessageHandler instance for advanced usage
- */
- getMessageHandler() {
- return this.messageHandler;
- }
- /**
- * Get MessageSender instance for advanced usage
- */
- getMessageSender() {
- return this.messageSender;
- }
- // ==========================================================================
- // PRIVATE METHODS
- // ==========================================================================
- /**
- * Setup event forwarding from MessageHandler to SDK events
- */
- setupEventForwarding() {
- // Forward gameReady
- this.messageHandler.on('gameReady', () => {
- this.isReady = true;
- this.emit('gameReady', undefined);
- // Auto-send queued data if enabled
- if (this.config.autoSendOnReady && this.pendingData) {
- setTimeout(() => {
- this.sendQueuedData();
- }, this.config.readyDelay);
- }
- });
- // Forward answerReport
- this.messageHandler.on('answerReport', (data) => {
- this.emit('answerReport', data);
- });
- // Forward finalResult
- this.messageHandler.on('finalResult', (data) => {
- this.emit('finalResult', data);
- });
- // Forward leaderboardRequest
- this.messageHandler.on('leaderboardRequest', (data) => {
- this.emit('leaderboardRequest', data);
- });
- // Forward errors
- this.messageHandler.on('error', (error) => {
- this.emit('error', error);
- });
- }
- /**
- * Send queued data
- */
- sendQueuedData() {
- if (this.pendingData) {
- this.sendGameData(this.pendingData);
- this.pendingData = null;
- }
- }
- /**
- * Internal logging
- */
- log(level, message, data) {
- if (this.config.debug) {
- const prefix = '[GameIframeSDK]';
- switch (level) {
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
- this.emit('log', { level, message, data });
- }
-}
-exports.GameIframeSDK = GameIframeSDK;
-// ==========================================================================
-// FACTORY / SINGLETON HELPERS
-// ==========================================================================
-let defaultInstance = null;
-/**
- * Create SDK instance
- */
-function createGameIframeSDK(config) {
- return new GameIframeSDK(config);
-}
-/**
- * Get or create default SDK instance
- */
-function getGameIframeSDK(config) {
- if (!defaultInstance && config) {
- defaultInstance = new GameIframeSDK(config);
- }
- if (!defaultInstance) {
- throw new Error('GameIframeSDK not initialized. Call with config first.');
- }
- return defaultInstance;
-}
-/**
- * Destroy default instance
- */
-function destroyGameIframeSDK() {
- defaultInstance?.destroy();
- defaultInstance = null;
-}
-//# sourceMappingURL=GameIframeSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/GameIframeSDK.js.map b/G102-sequence/sdk/package/dist/GameIframeSDK.js.map
deleted file mode 100644
index 2bed23f..0000000
--- a/G102-sequence/sdk/package/dist/GameIframeSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameIframeSDK.js","sourceRoot":"","sources":["../src/GameIframeSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageHandler.d.ts b/G102-sequence/sdk/package/dist/MessageHandler.d.ts
deleted file mode 100644
index ab2b7f4..0000000
--- a/G102-sequence/sdk/package/dist/MessageHandler.d.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Game Iframe SDK - Message Handler
- * Xử lý message từ iframe
- */
-import { AnswerReportData, FinalResultData } from './types';
-import { EventEmitter } from './EventEmitter';
-export interface MessageHandlerEvents {
- gameReady: void;
- answerReport: AnswerReportData;
- finalResult: FinalResultData;
- leaderboardRequest: {
- top: number;
- };
- unknownMessage: {
- type: string;
- data: any;
- };
- error: {
- message: string;
- error?: any;
- };
-}
-export interface MessageHandlerConfig {
- /**
- * Accepted origin (use '*' to accept all - not recommended for production)
- */
- acceptedOrigin: string;
- /**
- * Enable debug logging
- */
- debug?: boolean;
-}
-/**
- * MessageHandler - Xử lý incoming messages từ iframe
- */
-export declare class MessageHandler extends EventEmitter {
- private config;
- private boundHandler;
- private isListening;
- constructor(config: MessageHandlerConfig);
- /**
- * Start listening for messages
- */
- start(): this;
- /**
- * Stop listening for messages
- */
- stop(): this;
- /**
- * Check if handler is listening
- */
- isActive(): boolean;
- /**
- * Handle incoming message
- */
- private handleMessage;
- /**
- * Check if origin is allowed
- */
- private isOriginAllowed;
- /**
- * Debug log
- */
- private log;
- /**
- * Cleanup
- */
- destroy(): void;
-}
-//# sourceMappingURL=MessageHandler.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageHandler.d.ts.map b/G102-sequence/sdk/package/dist/MessageHandler.d.ts.map
deleted file mode 100644
index ece5d8f..0000000
--- a/G102-sequence/sdk/package/dist/MessageHandler.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../src/MessageHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAiB,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,WAAW,EAAE,eAAe,CAAC;IAC7B,kBAAkB,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,CAAC;IAC5C,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;CAC3C;AAED,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAClE,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,oBAAoB;IAKxC;;OAEG;IACH,KAAK,IAAI,IAAI;IAab;;OAEG;IACH,IAAI,IAAI,IAAI;IAWZ;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,OAAO,CAAC,aAAa;IAyCrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACH,OAAO,IAAI,IAAI;CAIlB"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageHandler.js b/G102-sequence/sdk/package/dist/MessageHandler.js
deleted file mode 100644
index a30bf16..0000000
--- a/G102-sequence/sdk/package/dist/MessageHandler.js
+++ /dev/null
@@ -1,115 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Message Handler
- * Xử lý message từ iframe
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.MessageHandler = void 0;
-const types_1 = require("./types");
-const EventEmitter_1 = require("./EventEmitter");
-/**
- * MessageHandler - Xử lý incoming messages từ iframe
- */
-class MessageHandler extends EventEmitter_1.EventEmitter {
- constructor(config) {
- super();
- this.boundHandler = null;
- this.isListening = false;
- this.config = config;
- }
- /**
- * Start listening for messages
- */
- start() {
- if (this.isListening) {
- return this;
- }
- this.boundHandler = this.handleMessage.bind(this);
- window.addEventListener('message', this.boundHandler);
- this.isListening = true;
- this.log('MessageHandler started');
- return this;
- }
- /**
- * Stop listening for messages
- */
- stop() {
- if (this.boundHandler) {
- window.removeEventListener('message', this.boundHandler);
- this.boundHandler = null;
- }
- this.isListening = false;
- this.log('MessageHandler stopped');
- return this;
- }
- /**
- * Check if handler is listening
- */
- isActive() {
- return this.isListening;
- }
- /**
- * Handle incoming message
- */
- handleMessage(event) {
- // Origin check
- if (!this.isOriginAllowed(event.origin)) {
- return;
- }
- const { type, data } = event.data || {};
- if (!type)
- return;
- this.log(`Received: ${type}`, data);
- try {
- switch (type) {
- case types_1.MESSAGE_TYPES.GAME_READY:
- this.emit('gameReady', undefined);
- break;
- case types_1.MESSAGE_TYPES.ANSWER_REPORT:
- // Raw data pass-through
- this.emit('answerReport', data);
- break;
- case types_1.MESSAGE_TYPES.FINAL_RESULT:
- // Raw data pass-through
- this.emit('finalResult', data);
- break;
- case types_1.MESSAGE_TYPES.GET_LEADERBOARD:
- this.emit('leaderboardRequest', { top: data?.top || 10 });
- break;
- default:
- this.emit('unknownMessage', { type, data });
- break;
- }
- }
- catch (error) {
- const err = error;
- this.emit('error', { message: `Error handling ${type}`, error: err });
- }
- }
- /**
- * Check if origin is allowed
- */
- isOriginAllowed(origin) {
- if (this.config.acceptedOrigin === '*') {
- return true;
- }
- return origin === this.config.acceptedOrigin;
- }
- /**
- * Debug log
- */
- log(message, data) {
- if (this.config.debug) {
- console.log('[MessageHandler]', message, data ?? '');
- }
- }
- /**
- * Cleanup
- */
- destroy() {
- this.stop();
- this.removeAllListeners();
- }
-}
-exports.MessageHandler = MessageHandler;
-//# sourceMappingURL=MessageHandler.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageHandler.js.map b/G102-sequence/sdk/package/dist/MessageHandler.js.map
deleted file mode 100644
index 813f39f..0000000
--- a/G102-sequence/sdk/package/dist/MessageHandler.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../src/MessageHandler.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageSender.d.ts b/G102-sequence/sdk/package/dist/MessageSender.d.ts
deleted file mode 100644
index 63d3175..0000000
--- a/G102-sequence/sdk/package/dist/MessageSender.d.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Game Iframe SDK - Message Sender
- * Gửi message đến iframe
- */
-import { PushDataPayload, LeaderboardData } from './types';
-export interface MessageSenderConfig {
- /**
- * Target origin for postMessage
- */
- targetOrigin: string;
- /**
- * Enable debug logging
- */
- debug?: boolean;
-}
-export interface SendResult {
- success: boolean;
- error?: Error;
-}
-/**
- * MessageSender - Gửi messages đến iframe
- */
-export declare class MessageSender {
- private config;
- private iframe;
- constructor(config: MessageSenderConfig);
- /**
- * Set iframe element
- */
- setIframe(iframe: HTMLIFrameElement | null): this;
- /**
- * Get current iframe
- */
- getIframe(): HTMLIFrameElement | null;
- /**
- * Check if iframe is available
- */
- isReady(): boolean;
- /**
- * Send raw message to iframe
- */
- sendRaw(message: any): SendResult;
- /**
- * Send game data (SERVER_PUSH_DATA)
- */
- sendGameData(payload: PushDataPayload): SendResult;
- /**
- * Send leaderboard (SERVER_PUSH_LEADERBOARD)
- */
- sendLeaderboard(data: LeaderboardData): SendResult;
- /**
- * Reload iframe
- */
- reloadIframe(): boolean;
- /**
- * Debug log
- */
- private log;
-}
-//# sourceMappingURL=MessageSender.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageSender.d.ts.map b/G102-sequence/sdk/package/dist/MessageSender.d.ts.map
deleted file mode 100644
index a9fff30..0000000
--- a/G102-sequence/sdk/package/dist/MessageSender.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageSender.d.ts","sourceRoot":"","sources":["../src/MessageSender.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAkC;gBAEpC,MAAM,EAAE,mBAAmB;IAIvC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAKjD;;OAEG;IACH,SAAS,IAAI,iBAAiB,GAAG,IAAI;IAIrC;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,UAAU;IAmBjC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,UAAU;IAoBlD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU;IAmBlD;;OAEG;IACH,YAAY,IAAI,OAAO;IAqBvB;;OAEG;IACH,OAAO,CAAC,GAAG;CAYd"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageSender.js b/G102-sequence/sdk/package/dist/MessageSender.js
deleted file mode 100644
index 672d5ac..0000000
--- a/G102-sequence/sdk/package/dist/MessageSender.js
+++ /dev/null
@@ -1,132 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Message Sender
- * Gửi message đến iframe
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.MessageSender = void 0;
-const types_1 = require("./types");
-/**
- * MessageSender - Gửi messages đến iframe
- */
-class MessageSender {
- constructor(config) {
- this.iframe = null;
- this.config = config;
- }
- /**
- * Set iframe element
- */
- setIframe(iframe) {
- this.iframe = iframe;
- return this;
- }
- /**
- * Get current iframe
- */
- getIframe() {
- return this.iframe;
- }
- /**
- * Check if iframe is available
- */
- isReady() {
- return !!this.iframe?.contentWindow;
- }
- /**
- * Send raw message to iframe
- */
- sendRaw(message) {
- if (!this.iframe?.contentWindow) {
- return {
- success: false,
- error: new Error('Iframe not available'),
- };
- }
- try {
- this.iframe.contentWindow.postMessage(message, this.config.targetOrigin);
- this.log('Sent message', { type: message.type });
- return { success: true };
- }
- catch (error) {
- const err = error;
- this.log('Send failed', { error: err.message });
- return { success: false, error: err };
- }
- }
- /**
- * Send game data (SERVER_PUSH_DATA)
- */
- sendGameData(payload) {
- // Inline message creation
- const message = {
- type: types_1.MESSAGE_TYPES.SERVER_PUSH_DATA,
- jsonData: payload,
- };
- const result = this.sendRaw(message);
- if (result.success) {
- const dataLength = payload.data?.length || 0;
- this.log('Sent game data', {
- game_id: payload.game_id,
- items: dataLength,
- });
- }
- return result;
- }
- /**
- * Send leaderboard (SERVER_PUSH_LEADERBOARD)
- */
- sendLeaderboard(data) {
- // Inline message creation
- const message = {
- type: types_1.MESSAGE_TYPES.SERVER_PUSH_LEADERBOARD,
- leaderboardData: data,
- };
- const result = this.sendRaw(message);
- if (result.success) {
- this.log('Sent leaderboard', {
- players: data.top_players?.length || 0,
- hasUserRank: !!data.user_rank,
- });
- }
- return result;
- }
- /**
- * Reload iframe
- */
- reloadIframe() {
- if (!this.iframe) {
- return false;
- }
- const currentSrc = this.iframe.src;
- if (!currentSrc || currentSrc === 'about:blank') {
- return false;
- }
- this.iframe.src = '';
- setTimeout(() => {
- if (this.iframe) {
- this.iframe.src = currentSrc;
- this.log('Iframe reloaded');
- }
- }, 100);
- return true;
- }
- /**
- * Debug log
- */
- log(message, data) {
- if (this.config.debug) {
- console.log('[MessageSender]', message);
- if (data) {
- try {
- console.log(JSON.stringify(data, null, 2));
- }
- catch (e) {
- console.log(data);
- }
- }
- }
- }
-}
-exports.MessageSender = MessageSender;
-//# sourceMappingURL=MessageSender.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/MessageSender.js.map b/G102-sequence/sdk/package/dist/MessageSender.js.map
deleted file mode 100644
index 069686d..0000000
--- a/G102-sequence/sdk/package/dist/MessageSender.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageSender.js","sourceRoot":"","sources":["../src/MessageSender.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/DataValidator.d.ts b/G102-sequence/sdk/package/dist/client/DataValidator.d.ts
deleted file mode 100644
index fcd3298..0000000
--- a/G102-sequence/sdk/package/dist/client/DataValidator.d.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Data Validator
- * Verify data structure cho từng game code
- *
- * Usage:
- * ```typescript
- * import { validateGameData, DataValidator } from 'game-iframe-sdk/client';
- *
- * const result = validateGameData('G001', receivedData);
- * if (!result.valid) {
- * console.error('Invalid data:', result.errors);
- * }
- * ```
- */
-import { GameCode } from '../kit/GameDataHandler';
-export interface ValidationResult {
- valid: boolean;
- errors: string[];
- warnings: string[];
-}
-export interface FieldSchema {
- type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'any';
- required: boolean;
- arrayItemType?: 'string' | 'number' | 'object' | 'any';
- description?: string;
-}
-export interface ItemSchema {
- [field: string]: FieldSchema;
-}
-/**
- * Validate game data payload
- */
-export declare function validateGameData(gameCode: GameCode, payload: any): ValidationResult;
-/**
- * Get schema for a game code
- */
-export declare function getSchema(gameCode: GameCode): ItemSchema | null;
-/**
- * Get schema documentation for a game code
- */
-export declare function getSchemaDoc(gameCode: GameCode): string;
-export declare class DataValidator {
- private gameCode;
- constructor(gameCode: GameCode);
- validate(payload: any): ValidationResult;
- getSchema(): ItemSchema | null;
- getSchemaDoc(): string;
-}
-//# sourceMappingURL=DataValidator.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/DataValidator.d.ts.map b/G102-sequence/sdk/package/dist/client/DataValidator.d.ts.map
deleted file mode 100644
index d6f461f..0000000
--- a/G102-sequence/sdk/package/dist/client/DataValidator.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"DataValidator.d.ts","sourceRoot":"","sources":["../../src/client/DataValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAc,MAAM,wBAAwB,CAAC;AAM9D,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnE,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;CAChC;AAoJD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,gBAAgB,CAmDnF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAyBvD;AAMD,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,EAAE,QAAQ;IAI9B,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,gBAAgB;IAIxC,SAAS,IAAI,UAAU,GAAG,IAAI;IAI9B,YAAY,IAAI,MAAM;CAGzB"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/DataValidator.js b/G102-sequence/sdk/package/dist/client/DataValidator.js
deleted file mode 100644
index bf05190..0000000
--- a/G102-sequence/sdk/package/dist/client/DataValidator.js
+++ /dev/null
@@ -1,252 +0,0 @@
-"use strict";
-/**
- * Data Validator
- * Verify data structure cho từng game code
- *
- * Usage:
- * ```typescript
- * import { validateGameData, DataValidator } from 'game-iframe-sdk/client';
- *
- * const result = validateGameData('G001', receivedData);
- * if (!result.valid) {
- * console.error('Invalid data:', result.errors);
- * }
- * ```
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.DataValidator = void 0;
-exports.validateGameData = validateGameData;
-exports.getSchema = getSchema;
-exports.getSchemaDoc = getSchemaDoc;
-const GameDataHandler_1 = require("../kit/GameDataHandler");
-// =============================================================================
-// SCHEMAS FOR EACH GAME CODE
-// =============================================================================
-const QUIZ_BASE_SCHEMA = {
- id: { type: 'string', required: true, description: 'Unique question ID' },
- options: { type: 'array', required: true, arrayItemType: 'string', description: 'Answer options' },
- answer: { type: 'number', required: true, description: 'Correct answer index (0-based)' },
-};
-const SCHEMAS = {
- // Quiz variants
- G001: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- },
- G002: {
- ...QUIZ_BASE_SCHEMA,
- question_audio: { type: 'string', required: true, description: 'Audio URL for question' },
- },
- G003: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- // options are audio URLs
- },
- G004: {
- ...QUIZ_BASE_SCHEMA,
- question_image: { type: 'string', required: true, description: 'Image URL for question' },
- question: { type: 'string', required: false, description: 'Optional text hint' },
- },
- // G005: Quiz Text-Image (options are image URLs, client picks index)
- G005: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- // options are image URLs, answer is index pointing to correct image
- },
- // Sequence Word variants
- G110: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true, description: 'The word to arrange' },
- parts: { type: 'array', required: true, arrayItemType: 'string', description: 'Letters/parts to arrange' },
- answer: { type: 'array', required: true, arrayItemType: 'string', description: 'Correct order' },
- },
- G111: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true, description: 'Audio hint URL' },
- },
- G112: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G113: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- // Sequence Sentence variants
- G120: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false, description: 'Full sentence (hint)' },
- parts: { type: 'array', required: true, arrayItemType: 'string', description: 'Words to arrange' },
- answer: { type: 'array', required: true, arrayItemType: 'string', description: 'Correct word order' },
- },
- G121: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G122: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G123: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- }
-};
-// =============================================================================
-// VALIDATOR
-// =============================================================================
-/**
- * Validate a single item against schema
- */
-function validateItem(item, schema, itemIndex) {
- const errors = [];
- if (!item || typeof item !== 'object') {
- errors.push(`Item [${itemIndex}]: Must be an object`);
- return errors;
- }
- for (const [field, fieldSchema] of Object.entries(schema)) {
- const value = item[field];
- // Check required
- if (fieldSchema.required && (value === undefined || value === null)) {
- errors.push(`Item [${itemIndex}].${field}: Required field is missing`);
- continue;
- }
- // Skip validation if optional and not present
- if (!fieldSchema.required && (value === undefined || value === null)) {
- continue;
- }
- // Check type
- const actualType = Array.isArray(value) ? 'array' : typeof value;
- if (fieldSchema.type !== 'any' && actualType !== fieldSchema.type) {
- errors.push(`Item [${itemIndex}].${field}: Expected ${fieldSchema.type}, got ${actualType}`);
- continue;
- }
- // Check array items
- if (fieldSchema.type === 'array' && fieldSchema.arrayItemType && fieldSchema.arrayItemType !== 'any') {
- for (let i = 0; i < value.length; i++) {
- const itemType = typeof value[i];
- if (itemType !== fieldSchema.arrayItemType) {
- errors.push(`Item [${itemIndex}].${field}[${i}]: Expected ${fieldSchema.arrayItemType}, got ${itemType}`);
- }
- }
- }
- }
- return errors;
-}
-/**
- * Validate game data payload
- */
-function validateGameData(gameCode, payload) {
- const errors = [];
- const warnings = [];
- // Check game code
- if (!GameDataHandler_1.GAME_CODES[gameCode]) {
- errors.push(`Unknown game code: ${gameCode}`);
- return { valid: false, errors, warnings };
- }
- // Check payload structure
- if (!payload || typeof payload !== 'object') {
- errors.push('Payload must be an object');
- return { valid: false, errors, warnings };
- }
- // Check data array
- const items = payload.data || payload.items || payload.questions;
- if (!items) {
- errors.push('Missing data array (expected "data", "items", or "questions")');
- return { valid: false, errors, warnings };
- }
- if (!Array.isArray(items)) {
- errors.push('"data" must be an array');
- return { valid: false, errors, warnings };
- }
- if (items.length === 0) {
- warnings.push('Data array is empty');
- }
- // Validate each item
- const schema = SCHEMAS[gameCode];
- for (let i = 0; i < items.length; i++) {
- const itemErrors = validateItem(items[i], schema, i);
- errors.push(...itemErrors);
- }
- // Check for duplicate IDs
- const ids = items.map((item) => item.id).filter(Boolean);
- const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
- if (duplicates.length > 0) {
- warnings.push(`Duplicate IDs found: ${[...new Set(duplicates)].join(', ')}`);
- }
- return {
- valid: errors.length === 0,
- errors,
- warnings,
- };
-}
-/**
- * Get schema for a game code
- */
-function getSchema(gameCode) {
- return SCHEMAS[gameCode] ?? null;
-}
-/**
- * Get schema documentation for a game code
- */
-function getSchemaDoc(gameCode) {
- const schema = SCHEMAS[gameCode];
- if (!schema)
- return `Unknown game code: ${gameCode}`;
- const gameInfo = GameDataHandler_1.GAME_CODES[gameCode];
- const lines = [
- `## ${gameCode}: ${gameInfo.name}`,
- `Category: ${gameInfo.category}`,
- '',
- '### Fields:',
- ];
- for (const [field, fieldSchema] of Object.entries(schema)) {
- const required = fieldSchema.required ? '(required)' : '(optional)';
- let type = fieldSchema.type;
- if (fieldSchema.arrayItemType) {
- type = `${fieldSchema.type}<${fieldSchema.arrayItemType}>`;
- }
- lines.push(`- **${field}**: ${type} ${required}`);
- if (fieldSchema.description) {
- lines.push(` - ${fieldSchema.description}`);
- }
- }
- return lines.join('\n');
-}
-// =============================================================================
-// DATA VALIDATOR CLASS
-// =============================================================================
-class DataValidator {
- constructor(gameCode) {
- this.gameCode = gameCode;
- }
- validate(payload) {
- return validateGameData(this.gameCode, payload);
- }
- getSchema() {
- return getSchema(this.gameCode);
- }
- getSchemaDoc() {
- return getSchemaDoc(this.gameCode);
- }
-}
-exports.DataValidator = DataValidator;
-//# sourceMappingURL=DataValidator.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/DataValidator.js.map b/G102-sequence/sdk/package/dist/client/DataValidator.js.map
deleted file mode 100644
index a434717..0000000
--- a/G102-sequence/sdk/package/dist/client/DataValidator.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"DataValidator.js","sourceRoot":"","sources":["../../src/client/DataValidator.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts b/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts
deleted file mode 100644
index f074e21..0000000
--- a/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * GameClientSDK - SDK dành cho Game Iframe
- *
- * Sử dụng trong game để:
- * - Tự động xác định mode (preview/live) từ URL
- * - Nhận data từ parent (preview) hoặc fetch API (live)
- * - Verify answers locally
- * - Report results về parent
- */
-import { GameCode } from '../kit/GameDataHandler';
-import { ValidationResult } from './DataValidator';
-export type ClientMode = 'preview' | 'live' | 'dev';
-export interface ClientSDKConfig {
- debug?: boolean;
- apiBaseUrl?: string;
- getAuthHeaders?: () => Record;
-}
-export interface URLParams {
- mode: ClientMode;
- gameCode: GameCode;
- gameId?: string;
- lid?: string;
- studentId?: string;
-}
-export interface GameDataPayload {
- game_id: string;
- game_code: GameCode;
- data: any[];
- completed_question_ids?: Array<{
- id: string;
- result: 0 | 1;
- }>;
-}
-export interface AnswerResult {
- isCorrect: boolean;
- score: number;
- feedback?: string;
-}
-export interface FinalResult {
- score: number;
- total: number;
- correct: number;
- wrong: number;
- details: Array<{
- question_id: string;
- choice: any;
- result: 0 | 1;
- time_spent: number;
- }>;
-}
-export interface ClientSDKEvents {
- ready: void;
- dataReceived: {
- items: any[];
- resumeData?: any[];
- validation?: ValidationResult;
- };
- error: {
- message: string;
- error?: any;
- };
- modeDetected: {
- mode: ClientMode;
- params: URLParams;
- };
- validationError: {
- validation: ValidationResult;
- };
-}
-type EventHandler = (data: T) => void;
-declare class SimpleEventEmitter> {
- private handlers;
- on(event: K, handler: EventHandler): () => void;
- off(event: K, handler: EventHandler): void;
- protected emit(event: K, data: Events[K]): void;
-}
-export declare class GameClientSDK extends SimpleEventEmitter {
- private config;
- private params;
- private mode;
- private originalItems;
- private sanitizedItems;
- private userAnswers;
- private isInitialized;
- private startTime;
- constructor(config?: ClientSDKConfig);
- /**
- * Get current mode
- */
- getMode(): ClientMode;
- /**
- * Get URL params
- */
- getParams(): URLParams;
- /**
- * Get game code
- */
- getGameCode(): GameCode;
- /**
- * Get sanitized items (safe for rendering)
- */
- getItems(): any[];
- /**
- * Submit an answer and get verification result
- */
- submitAnswer(questionId: string, choice: any): AnswerResult;
- /**
- * Get final result
- */
- getFinalResult(): FinalResult;
- /**
- * Report final result to parent
- */
- reportFinalResult(result?: FinalResult): void;
- /**
- * Request leaderboard from parent
- */
- requestLeaderboard(top?: number): void;
- /**
- * Cleanup
- */
- destroy(): void;
- private parseURLParams;
- private setupMessageListener;
- private handleMessage;
- private initialize;
- /**
- * Load mock data for dev mode
- */
- private loadMockData;
- private sendGameReady;
- private fetchLiveData;
- private handleDataReceived;
- private sendAnswerReport;
- private log;
-}
-/**
- * Get or create GameClientSDK instance
- */
-export declare function getGameClientSDK(config?: ClientSDKConfig): GameClientSDK;
-/**
- * Destroy client instance
- */
-export declare function destroyGameClientSDK(): void;
-export {};
-//# sourceMappingURL=GameClientSDK.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts.map b/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts.map
deleted file mode 100644
index 6c51c12..0000000
--- a/G102-sequence/sdk/package/dist/client/GameClientSDK.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameClientSDK.d.ts","sourceRoot":"","sources":["../../src/client/GameClientSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/GameClientSDK.js b/G102-sequence/sdk/package/dist/client/GameClientSDK.js
deleted file mode 100644
index 3c99487..0000000
--- a/G102-sequence/sdk/package/dist/client/GameClientSDK.js
+++ /dev/null
@@ -1,365 +0,0 @@
-"use strict";
-/**
- * GameClientSDK - SDK dành cho Game Iframe
- *
- * Sử dụng trong game để:
- * - Tự động xác định mode (preview/live) từ URL
- * - Nhận data từ parent (preview) hoặc fetch API (live)
- * - Verify answers locally
- * - Report results về parent
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GameClientSDK = void 0;
-exports.getGameClientSDK = getGameClientSDK;
-exports.destroyGameClientSDK = destroyGameClientSDK;
-const GameDataHandler_1 = require("../kit/GameDataHandler");
-const MockData_1 = require("./MockData");
-const DataValidator_1 = require("./DataValidator");
-class SimpleEventEmitter {
- constructor() {
- this.handlers = new Map();
- }
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- return () => this.off(event, handler);
- }
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- console.error(`[GameClientSDK] Error in ${String(event)} handler:`, err);
- }
- });
- }
-}
-// =============================================================================
-// GAME CLIENT SDK
-// =============================================================================
-class GameClientSDK extends SimpleEventEmitter {
- constructor(config = {}) {
- super();
- // Data storage
- this.originalItems = new Map(); // Có đáp án
- this.sanitizedItems = []; // Không có đáp án
- this.userAnswers = new Map();
- this.isInitialized = false;
- this.startTime = 0;
- this.config = {
- debug: config.debug ?? false,
- apiBaseUrl: config.apiBaseUrl ?? '',
- getAuthHeaders: config.getAuthHeaders ?? (() => ({})),
- };
- // Parse URL params
- this.params = this.parseURLParams();
- this.mode = this.params.mode;
- this.log('info', 'SDK created', { mode: this.mode, params: this.params });
- // Emit mode detected
- this.emit('modeDetected', { mode: this.mode, params: this.params });
- // Setup message listener
- this.setupMessageListener();
- // Auto-initialize based on mode
- this.initialize();
- }
- // ==========================================================================
- // PUBLIC API
- // ==========================================================================
- /**
- * Get current mode
- */
- getMode() {
- return this.mode;
- }
- /**
- * Get URL params
- */
- getParams() {
- return { ...this.params };
- }
- /**
- * Get game code
- */
- getGameCode() {
- return this.params.gameCode;
- }
- /**
- * Get sanitized items (safe for rendering)
- */
- getItems() {
- return this.sanitizedItems;
- }
- /**
- * Submit an answer and get verification result
- */
- submitAnswer(questionId, choice) {
- const originalItem = this.originalItems.get(questionId);
- if (!originalItem) {
- this.log('warn', `Item not found: ${questionId}`);
- return { isCorrect: false, score: 0, feedback: 'Question not found' };
- }
- // Verify using GameDataHandler
- const result = (0, GameDataHandler_1.checkAnswer)(this.params.gameCode, originalItem, choice);
- // Store user answer
- const timeSpent = Date.now() - (this.userAnswers.size === 0 ? this.startTime : Date.now());
- this.userAnswers.set(questionId, {
- choice,
- result: result.isCorrect ? 1 : 0,
- time: timeSpent,
- });
- // Report to parent
- this.sendAnswerReport(questionId, choice, result.isCorrect ? 1 : 0, timeSpent);
- this.log('info', `Answer submitted: ${questionId}`, { choice, result });
- return result;
- }
- /**
- * Get final result
- */
- getFinalResult() {
- const details = Array.from(this.userAnswers.entries()).map(([id, data]) => ({
- question_id: id,
- choice: data.choice,
- result: data.result,
- time_spent: data.time,
- }));
- const correct = details.filter(d => d.result === 1).length;
- const total = this.originalItems.size;
- return {
- score: total > 0 ? Math.round((correct / total) * 100) : 0,
- total,
- correct,
- wrong: total - correct,
- details,
- };
- }
- /**
- * Report final result to parent
- */
- reportFinalResult(result) {
- const finalResult = result ?? this.getFinalResult();
- window.parent.postMessage({
- type: 'FINAL_RESULT',
- data: finalResult,
- }, '*');
- this.log('info', 'Final result reported', finalResult);
- }
- /**
- * Request leaderboard from parent
- */
- requestLeaderboard(top = 10) {
- window.parent.postMessage({
- type: 'GET_LEADERBOARD',
- data: { top },
- }, '*');
- }
- /**
- * Cleanup
- */
- destroy() {
- window.removeEventListener('message', this.handleMessage);
- this.originalItems.clear();
- this.sanitizedItems = [];
- this.userAnswers.clear();
- this.log('info', 'SDK destroyed');
- }
- // ==========================================================================
- // PRIVATE METHODS
- // ==========================================================================
- parseURLParams() {
- const searchParams = new URLSearchParams(window.location.search);
- const mode = (searchParams.get('mode') || 'preview');
- const gameCode = (searchParams.get('game_code') || 'G001');
- const gameId = searchParams.get('game_id') || undefined;
- const lid = searchParams.get('lid') || undefined;
- const studentId = searchParams.get('student_id') || undefined;
- // Validate mode
- if (mode !== 'preview' && mode !== 'live' && mode !== 'dev') {
- this.log('warn', `Invalid mode: ${mode}, defaulting to preview`);
- }
- // Validate game code
- if (!GameDataHandler_1.GAME_CODES[gameCode]) {
- this.log('warn', `Unknown game code: ${gameCode}`);
- }
- return { mode, gameCode, gameId, lid, studentId };
- }
- setupMessageListener() {
- this.handleMessage = this.handleMessage.bind(this);
- window.addEventListener('message', this.handleMessage);
- }
- handleMessage(event) {
- const { type, jsonData, leaderboardData } = event.data || {};
- this.log('debug', 'Message received', { type, hasData: !!jsonData });
- switch (type) {
- case 'SERVER_PUSH_DATA':
- if (jsonData) {
- this.handleDataReceived(jsonData);
- }
- break;
- case 'SERVER_PUSH_LEADERBOARD':
- if (leaderboardData) {
- this.log('info', 'Leaderboard received', leaderboardData);
- // Could emit event here
- }
- break;
- }
- }
- async initialize() {
- // Send GAME_READY immediately
- this.sendGameReady();
- if (this.mode === 'dev') {
- // Dev mode: load mock data immediately
- this.log('info', 'DEV MODE: Loading mock data...');
- this.loadMockData();
- }
- else if (this.mode === 'live') {
- // Live mode: fetch data from API
- await this.fetchLiveData();
- }
- else {
- // Preview mode: wait for postMessage
- this.log('info', 'Preview mode: waiting for SERVER_PUSH_DATA...');
- }
- }
- /**
- * Load mock data for dev mode
- */
- loadMockData() {
- const mockData = (0, MockData_1.getMockData)(this.params.gameCode);
- if (!mockData) {
- this.emit('error', {
- message: `No mock data available for game code: ${this.params.gameCode}`
- });
- return;
- }
- this.log('info', `Loaded mock data for ${this.params.gameCode}`);
- this.handleDataReceived(mockData);
- }
- sendGameReady() {
- window.parent.postMessage({ type: 'GAME_READY' }, '*');
- this.emit('ready', undefined);
- this.log('info', 'GAME_READY sent');
- }
- async fetchLiveData() {
- const { gameId, lid } = this.params;
- if (!gameId || !lid) {
- this.emit('error', { message: 'Live mode requires game_id and lid' });
- return;
- }
- if (!this.config.apiBaseUrl) {
- this.emit('error', { message: 'Live mode requires apiBaseUrl' });
- return;
- }
- try {
- const url = `${this.config.apiBaseUrl}/games/${gameId}?lid=${lid}`;
- const headers = {
- 'Content-Type': 'application/json',
- ...this.config.getAuthHeaders(),
- };
- this.log('info', `Fetching live data: ${url}`);
- const response = await fetch(url, { headers });
- if (!response.ok) {
- throw new Error(`API Error: ${response.status}`);
- }
- const data = await response.json();
- this.handleDataReceived(data);
- }
- catch (error) {
- this.log('error', 'Failed to fetch live data', error);
- this.emit('error', { message: 'Failed to fetch game data', error });
- }
- }
- handleDataReceived(payload) {
- this.startTime = Date.now();
- // Update game code if provided
- if (payload.game_code && GameDataHandler_1.GAME_CODES[payload.game_code]) {
- this.params.gameCode = payload.game_code;
- }
- // Validate data structure
- const validation = (0, DataValidator_1.validateGameData)(this.params.gameCode, payload);
- if (!validation.valid) {
- this.log('error', 'Data validation failed', validation.errors);
- this.emit('validationError', { validation });
- // Continue anyway to allow partial rendering
- }
- if (validation.warnings.length > 0) {
- this.log('warn', 'Data validation warnings', validation.warnings);
- }
- // Extract items from various payload formats
- const items = payload.data || payload.items || payload.questions || [];
- const resumeData = payload.completed_question_ids || [];
- // Store original items (with answers)
- this.originalItems.clear();
- items.forEach((item) => {
- if (item.id) {
- this.originalItems.set(item.id, item);
- }
- });
- // Sanitize for client (remove answers)
- this.sanitizedItems = (0, GameDataHandler_1.sanitizeForClient)(this.params.gameCode, items);
- this.isInitialized = true;
- this.log('info', `Data received: ${items.length} items, ${resumeData.length} completed`);
- // Emit event with validation result
- this.emit('dataReceived', {
- items: this.sanitizedItems,
- resumeData,
- validation,
- });
- }
- sendAnswerReport(questionId, choice, result, timeSpent) {
- window.parent.postMessage({
- type: 'ANSWER_REPORT',
- data: {
- question_id: questionId,
- question_index: Array.from(this.originalItems.keys()).indexOf(questionId),
- choice,
- result,
- time_spent: timeSpent,
- },
- }, '*');
- }
- log(level, message, data) {
- if (!this.config.debug && level === 'debug')
- return;
- const prefix = `[GameClientSDK:${this.mode}]`;
- switch (level) {
- case 'debug':
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
-}
-exports.GameClientSDK = GameClientSDK;
-// =============================================================================
-// FACTORY
-// =============================================================================
-let clientInstance = null;
-/**
- * Get or create GameClientSDK instance
- */
-function getGameClientSDK(config) {
- if (!clientInstance) {
- clientInstance = new GameClientSDK(config);
- }
- return clientInstance;
-}
-/**
- * Destroy client instance
- */
-function destroyGameClientSDK() {
- clientInstance?.destroy();
- clientInstance = null;
-}
-//# sourceMappingURL=GameClientSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/GameClientSDK.js.map b/G102-sequence/sdk/package/dist/client/GameClientSDK.js.map
deleted file mode 100644
index d495545..0000000
--- a/G102-sequence/sdk/package/dist/client/GameClientSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameClientSDK.js","sourceRoot":"","sources":["../../src/client/GameClientSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/MockData.d.ts b/G102-sequence/sdk/package/dist/client/MockData.d.ts
deleted file mode 100644
index 926fc6d..0000000
--- a/G102-sequence/sdk/package/dist/client/MockData.d.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * Mock Data cho từng Game Code
- * Game developers dùng để test game standalone
- *
- * Usage:
- * ```typescript
- * import { MockData } from 'game-iframe-sdk/client';
- *
- * // Lấy sample data cho Quiz Text-Text
- * const quizData = MockData.G001;
- *
- * // Lấy sample data cho Sequence Word
- * const seqData = MockData.G110;
- * ```
- */
-import { GameCode } from '../kit/GameDataHandler';
-/** G001: Quiz Text-Text */
-export declare const MOCK_G001: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- question: string;
- options: string[];
- answer: number;
- }[];
-};
-/** G002: Quiz Audio-Text */
-export declare const MOCK_G002: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- question_audio: string;
- options: string[];
- answer: number;
- }[];
-};
-/** G003: Quiz Text-Audio */
-export declare const MOCK_G003: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- question: string;
- options: string[];
- answer: number;
- }[];
-};
-/** G004: Quiz Image-Text */
-export declare const MOCK_G004: {
- game_code: GameCode;
- game_id: string;
- data: ({
- id: string;
- question_image: string;
- question: string;
- options: string[];
- answer: number;
- } | {
- id: string;
- question_image: string;
- options: string[];
- answer: number;
- question?: undefined;
- })[];
-};
-/** G005: Quiz Text-Image */
-export declare const MOCK_G005: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- question: string;
- options: string[];
- answer: number;
- }[];
-};
-/** G110: Sequence Word - no audio */
-export declare const MOCK_G110: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- word: string;
- parts: string[];
- answer: string[];
- }[];
-};
-/** G111: Sequence Word - audio, hide 2 */
-export declare const MOCK_G111: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- word: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-/** G112: Sequence Word - audio, hide 4 */
-export declare const MOCK_G112: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- word: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-/** G113: Sequence Word - audio, hide all */
-export declare const MOCK_G113: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- word: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-/** G120: Sequence Sentence - no audio */
-export declare const MOCK_G120: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- sentence: string;
- parts: string[];
- answer: string[];
- }[];
-};
-/** G121: Sequence Sentence - audio, hide 2 */
-export declare const MOCK_G121: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- sentence: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-/** G122: Sequence Sentence - audio, hide 4 */
-export declare const MOCK_G122: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- sentence: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-/** G123: Sequence Sentence - audio, hide all */
-export declare const MOCK_G123: {
- game_code: GameCode;
- game_id: string;
- data: {
- id: string;
- sentence: string;
- parts: string[];
- answer: string[];
- audio_url: string;
- }[];
-};
-export declare const MockData: Record;
-/**
- * Get mock data for a game code
- */
-export declare function getMockData(code: GameCode): any;
-/**
- * Get all available game codes
- */
-export declare function getAvailableGameCodes(): GameCode[];
-//# sourceMappingURL=MockData.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/MockData.d.ts.map b/G102-sequence/sdk/package/dist/client/MockData.d.ts.map
deleted file mode 100644
index ae91d18..0000000
--- a/G102-sequence/sdk/package/dist/client/MockData.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MockData.d.ts","sourceRoot":"","sources":["../../src/client/MockData.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAMlD,2BAA2B;AAC3B,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAsBhC,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAgBhC,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAchC,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;;;;;;;CAiBhC,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAchC,CAAC;AAMF,qCAAqC;AACrC,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAsBhC,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAMF,yCAAyC;AACzC,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;CAgBhC,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,SAAS;eACG,QAAQ;;;;;;;;;CAWhC,CAAC;AAMF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,GAAG,CAiB1C,CAAC;AAEF;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAE/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,QAAQ,EAAE,CAElD"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/MockData.js b/G102-sequence/sdk/package/dist/client/MockData.js
deleted file mode 100644
index ea94250..0000000
--- a/G102-sequence/sdk/package/dist/client/MockData.js
+++ /dev/null
@@ -1,289 +0,0 @@
-"use strict";
-/**
- * Mock Data cho từng Game Code
- * Game developers dùng để test game standalone
- *
- * Usage:
- * ```typescript
- * import { MockData } from 'game-iframe-sdk/client';
- *
- * // Lấy sample data cho Quiz Text-Text
- * const quizData = MockData.G001;
- *
- * // Lấy sample data cho Sequence Word
- * const seqData = MockData.G110;
- * ```
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.MockData = exports.MOCK_G123 = exports.MOCK_G122 = exports.MOCK_G121 = exports.MOCK_G120 = exports.MOCK_G113 = exports.MOCK_G112 = exports.MOCK_G111 = exports.MOCK_G110 = exports.MOCK_G005 = exports.MOCK_G004 = exports.MOCK_G003 = exports.MOCK_G002 = exports.MOCK_G001 = void 0;
-exports.getMockData = getMockData;
-exports.getAvailableGameCodes = getAvailableGameCodes;
-// =============================================================================
-// QUIZ MOCK DATA
-// =============================================================================
-/** G001: Quiz Text-Text */
-exports.MOCK_G001 = {
- game_code: 'G001',
- game_id: 'mock-quiz-text-text',
- data: [
- {
- id: 'q1',
- question: 'Thủ đô của Việt Nam là gì?',
- options: ['Hà Nội', 'Hồ Chí Minh', 'Đà Nẵng', 'Huế'],
- answer: 0, // Index của đáp án đúng
- },
- {
- id: 'q2',
- question: '2 + 2 = ?',
- options: ['3', '4', '5', '6'],
- answer: 1,
- },
- {
- id: 'q3',
- question: 'Con vật nào biết bay?',
- options: ['Chó', 'Mèo', 'Chim', 'Cá'],
- answer: 2,
- },
- ],
-};
-/** G002: Quiz Audio-Text */
-exports.MOCK_G002 = {
- game_code: 'G002',
- game_id: 'mock-quiz-audio-text',
- data: [
- {
- id: 'q1',
- question_audio: 'https://example.com/audio/question1.mp3',
- options: ['Apple', 'Banana', 'Orange', 'Grape'],
- answer: 0,
- },
- {
- id: 'q2',
- question_audio: 'https://example.com/audio/question2.mp3',
- options: ['Dog', 'Cat', 'Bird', 'Fish'],
- answer: 2,
- },
- ],
-};
-/** G003: Quiz Text-Audio */
-exports.MOCK_G003 = {
- game_code: 'G003',
- game_id: 'mock-quiz-text-audio',
- data: [
- {
- id: 'q1',
- question: 'Chọn phát âm đúng của từ "Hello"',
- options: [
- 'https://example.com/audio/hello1.mp3',
- 'https://example.com/audio/hello2.mp3',
- 'https://example.com/audio/hello3.mp3',
- ],
- answer: 0,
- },
- ],
-};
-/** G004: Quiz Image-Text */
-exports.MOCK_G004 = {
- game_code: 'G004',
- game_id: 'mock-quiz-image-text',
- data: [
- {
- id: 'q1',
- question_image: 'https://example.com/images/apple.jpg',
- question: 'Đây là quả gì?', // Optional hint
- options: ['Táo', 'Cam', 'Chuối', 'Nho'],
- answer: 0,
- },
- {
- id: 'q2',
- question_image: 'https://example.com/images/cat.jpg',
- options: ['Chó', 'Mèo', 'Thỏ', 'Chuột'],
- answer: 1,
- },
- ],
-};
-/** G005: Quiz Text-Image */
-exports.MOCK_G005 = {
- game_code: 'G005',
- game_id: 'mock-quiz-text-image',
- data: [
- {
- id: 'q1',
- question: 'Chọn hình ảnh con mèo',
- options: [
- 'https://example.com/images/dog.jpg',
- 'https://example.com/images/cat.jpg',
- 'https://example.com/images/bird.jpg',
- ],
- answer: 1,
- },
- ],
-};
-// =============================================================================
-// SEQUENCE WORD MOCK DATA
-// =============================================================================
-/** G110: Sequence Word - no audio */
-exports.MOCK_G110 = {
- game_code: 'G110',
- game_id: 'mock-sequence-word',
- data: [
- {
- id: 'sw1',
- word: 'APPLE',
- parts: ['A', 'P', 'P', 'L', 'E'], // Đáp án đúng theo thứ tự
- answer: ['A', 'P', 'P', 'L', 'E'], // SDK sẽ shuffle parts, giữ answer để verify
- },
- {
- id: 'sw2',
- word: 'HELLO',
- parts: ['H', 'E', 'L', 'L', 'O'],
- answer: ['H', 'E', 'L', 'L', 'O'],
- },
- {
- id: 'sw3',
- word: 'WORLD',
- parts: ['W', 'O', 'R', 'L', 'D'],
- answer: ['W', 'O', 'R', 'L', 'D'],
- },
- ],
-};
-/** G111: Sequence Word - audio, hide 2 */
-exports.MOCK_G111 = {
- game_code: 'G111',
- game_id: 'mock-sequence-word-audio-2',
- data: [
- {
- id: 'sw1',
- word: 'BANANA',
- parts: ['B', 'A', 'N', 'A', 'N', 'A'],
- answer: ['B', 'A', 'N', 'A', 'N', 'A'],
- audio_url: 'https://example.com/audio/banana.mp3',
- },
- ],
-};
-/** G112: Sequence Word - audio, hide 4 */
-exports.MOCK_G112 = {
- game_code: 'G112',
- game_id: 'mock-sequence-word-audio-4',
- data: [
- {
- id: 'sw1',
- word: 'COMPUTER',
- parts: ['C', 'O', 'M', 'P', 'U', 'T', 'E', 'R'],
- answer: ['C', 'O', 'M', 'P', 'U', 'T', 'E', 'R'],
- audio_url: 'https://example.com/audio/computer.mp3',
- },
- ],
-};
-/** G113: Sequence Word - audio, hide all */
-exports.MOCK_G113 = {
- game_code: 'G113',
- game_id: 'mock-sequence-word-audio-all',
- data: [
- {
- id: 'sw1',
- word: 'ELEPHANT',
- parts: ['E', 'L', 'E', 'P', 'H', 'A', 'N', 'T'],
- answer: ['E', 'L', 'E', 'P', 'H', 'A', 'N', 'T'],
- audio_url: 'https://example.com/audio/elephant.mp3',
- },
- ],
-};
-// =============================================================================
-// SEQUENCE SENTENCE MOCK DATA
-// =============================================================================
-/** G120: Sequence Sentence - no audio */
-exports.MOCK_G120 = {
- game_code: 'G120',
- game_id: 'mock-sequence-sentence',
- data: [
- {
- id: 'ss1',
- sentence: 'I love learning English.',
- parts: ['I', 'love', 'learning', 'English.'],
- answer: ['I', 'love', 'learning', 'English.'],
- },
- {
- id: 'ss2',
- sentence: 'The cat is sleeping.',
- parts: ['The', 'cat', 'is', 'sleeping.'],
- answer: ['The', 'cat', 'is', 'sleeping.'],
- },
- ],
-};
-/** G121: Sequence Sentence - audio, hide 2 */
-exports.MOCK_G121 = {
- game_code: 'G121',
- game_id: 'mock-sequence-sentence-audio-2',
- data: [
- {
- id: 'ss1',
- sentence: 'She goes to school every day.',
- parts: ['She', 'goes', 'to', 'school', 'every', 'day.'],
- answer: ['She', 'goes', 'to', 'school', 'every', 'day.'],
- audio_url: 'https://example.com/audio/sentence1.mp3',
- },
- ],
-};
-/** G122: Sequence Sentence - audio, hide 4 */
-exports.MOCK_G122 = {
- game_code: 'G122',
- game_id: 'mock-sequence-sentence-audio-4',
- data: [
- {
- id: 'ss1',
- sentence: 'My brother plays football in the park.',
- parts: ['My', 'brother', 'plays', 'football', 'in', 'the', 'park.'],
- answer: ['My', 'brother', 'plays', 'football', 'in', 'the', 'park.'],
- audio_url: 'https://example.com/audio/sentence2.mp3',
- },
- ],
-};
-/** G123: Sequence Sentence - audio, hide all */
-exports.MOCK_G123 = {
- game_code: 'G123',
- game_id: 'mock-sequence-sentence-audio-all',
- data: [
- {
- id: 'ss1',
- sentence: 'The quick brown fox jumps over the lazy dog.',
- parts: ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog.'],
- answer: ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog.'],
- audio_url: 'https://example.com/audio/sentence3.mp3',
- },
- ],
-};
-// =============================================================================
-// MOCK DATA MAP
-// =============================================================================
-exports.MockData = {
- // Quiz
- G001: exports.MOCK_G001,
- G002: exports.MOCK_G002,
- G003: exports.MOCK_G003,
- G004: exports.MOCK_G004,
- // Sequence Word
- G110: exports.MOCK_G110,
- G111: exports.MOCK_G111,
- G112: exports.MOCK_G112,
- G113: exports.MOCK_G113,
- // Sequence Sentence
- G120: exports.MOCK_G120,
- G121: exports.MOCK_G121,
- G122: exports.MOCK_G122,
- G123: exports.MOCK_G123,
- G005: exports.MOCK_G005,
-};
-/**
- * Get mock data for a game code
- */
-function getMockData(code) {
- return exports.MockData[code] ?? null;
-}
-/**
- * Get all available game codes
- */
-function getAvailableGameCodes() {
- return Object.keys(exports.MockData);
-}
-//# sourceMappingURL=MockData.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/MockData.js.map b/G102-sequence/sdk/package/dist/client/MockData.js.map
deleted file mode 100644
index 40b3d0c..0000000
--- a/G102-sequence/sdk/package/dist/client/MockData.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MockData.js","sourceRoot":"","sources":["../../src/client/MockData.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/index.d.ts b/G102-sequence/sdk/package/dist/client/index.d.ts
deleted file mode 100644
index 95297ca..0000000
--- a/G102-sequence/sdk/package/dist/client/index.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Client SDK exports
- * SDK dành cho game developers sử dụng trong game iframe
- */
-export { GameClientSDK, getGameClientSDK, destroyGameClientSDK, type ClientMode, type ClientSDKConfig, type URLParams, type GameDataPayload, type AnswerResult, type FinalResult, type ClientSDKEvents, } from './GameClientSDK';
-export { MockData, getMockData, getAvailableGameCodes, MOCK_G001, MOCK_G002, MOCK_G003, MOCK_G004, MOCK_G110, MOCK_G111, MOCK_G112, MOCK_G113, MOCK_G120, MOCK_G121, MOCK_G122, MOCK_G123, } from './MockData';
-export { validateGameData, getSchema, getSchemaDoc, DataValidator, type ValidationResult, type FieldSchema, type ItemSchema, } from './DataValidator';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/index.d.ts.map b/G102-sequence/sdk/package/dist/client/index.d.ts.map
deleted file mode 100644
index 1918946..0000000
--- a/G102-sequence/sdk/package/dist/client/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,GACvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACH,QAAQ,EACR,WAAW,EACX,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,UAAU,GAClB,MAAM,iBAAiB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/index.js b/G102-sequence/sdk/package/dist/client/index.js
deleted file mode 100644
index cc3f246..0000000
--- a/G102-sequence/sdk/package/dist/client/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-/**
- * Client SDK exports
- * SDK dành cho game developers sử dụng trong game iframe
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.DataValidator = exports.getSchemaDoc = exports.getSchema = exports.validateGameData = exports.MOCK_G123 = exports.MOCK_G122 = exports.MOCK_G121 = exports.MOCK_G120 = exports.MOCK_G113 = exports.MOCK_G112 = exports.MOCK_G111 = exports.MOCK_G110 = exports.MOCK_G004 = exports.MOCK_G003 = exports.MOCK_G002 = exports.MOCK_G001 = exports.getAvailableGameCodes = exports.getMockData = exports.MockData = exports.destroyGameClientSDK = exports.getGameClientSDK = exports.GameClientSDK = void 0;
-var GameClientSDK_1 = require("./GameClientSDK");
-Object.defineProperty(exports, "GameClientSDK", { enumerable: true, get: function () { return GameClientSDK_1.GameClientSDK; } });
-Object.defineProperty(exports, "getGameClientSDK", { enumerable: true, get: function () { return GameClientSDK_1.getGameClientSDK; } });
-Object.defineProperty(exports, "destroyGameClientSDK", { enumerable: true, get: function () { return GameClientSDK_1.destroyGameClientSDK; } });
-// Mock Data - sample data cho từng game code
-var MockData_1 = require("./MockData");
-Object.defineProperty(exports, "MockData", { enumerable: true, get: function () { return MockData_1.MockData; } });
-Object.defineProperty(exports, "getMockData", { enumerable: true, get: function () { return MockData_1.getMockData; } });
-Object.defineProperty(exports, "getAvailableGameCodes", { enumerable: true, get: function () { return MockData_1.getAvailableGameCodes; } });
-Object.defineProperty(exports, "MOCK_G001", { enumerable: true, get: function () { return MockData_1.MOCK_G001; } });
-Object.defineProperty(exports, "MOCK_G002", { enumerable: true, get: function () { return MockData_1.MOCK_G002; } });
-Object.defineProperty(exports, "MOCK_G003", { enumerable: true, get: function () { return MockData_1.MOCK_G003; } });
-Object.defineProperty(exports, "MOCK_G004", { enumerable: true, get: function () { return MockData_1.MOCK_G004; } });
-Object.defineProperty(exports, "MOCK_G110", { enumerable: true, get: function () { return MockData_1.MOCK_G110; } });
-Object.defineProperty(exports, "MOCK_G111", { enumerable: true, get: function () { return MockData_1.MOCK_G111; } });
-Object.defineProperty(exports, "MOCK_G112", { enumerable: true, get: function () { return MockData_1.MOCK_G112; } });
-Object.defineProperty(exports, "MOCK_G113", { enumerable: true, get: function () { return MockData_1.MOCK_G113; } });
-Object.defineProperty(exports, "MOCK_G120", { enumerable: true, get: function () { return MockData_1.MOCK_G120; } });
-Object.defineProperty(exports, "MOCK_G121", { enumerable: true, get: function () { return MockData_1.MOCK_G121; } });
-Object.defineProperty(exports, "MOCK_G122", { enumerable: true, get: function () { return MockData_1.MOCK_G122; } });
-Object.defineProperty(exports, "MOCK_G123", { enumerable: true, get: function () { return MockData_1.MOCK_G123; } });
-// Data Validator - verify data structure
-var DataValidator_1 = require("./DataValidator");
-Object.defineProperty(exports, "validateGameData", { enumerable: true, get: function () { return DataValidator_1.validateGameData; } });
-Object.defineProperty(exports, "getSchema", { enumerable: true, get: function () { return DataValidator_1.getSchema; } });
-Object.defineProperty(exports, "getSchemaDoc", { enumerable: true, get: function () { return DataValidator_1.getSchemaDoc; } });
-Object.defineProperty(exports, "DataValidator", { enumerable: true, get: function () { return DataValidator_1.DataValidator; } });
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/client/index.js.map b/G102-sequence/sdk/package/dist/client/index.js.map
deleted file mode 100644
index 83f0913..0000000
--- a/G102-sequence/sdk/package/dist/client/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,iDAWyB;AAVrB,8GAAA,aAAa,OAAA;AACb,iHAAA,gBAAgB,OAAA;AAChB,qHAAA,oBAAoB,OAAA;AAUxB,6CAA6C;AAC7C,uCAgBoB;AAfhB,oGAAA,QAAQ,OAAA;AACR,uGAAA,WAAW,OAAA;AACX,iHAAA,qBAAqB,OAAA;AACrB,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AACT,qGAAA,SAAS,OAAA;AAGb,yCAAyC;AACzC,iDAQyB;AAPrB,iHAAA,gBAAgB,OAAA;AAChB,0GAAA,SAAS,OAAA;AACT,6GAAA,YAAY,OAAA;AACZ,8GAAA,aAAa,OAAA"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/EventEmitter.js b/G102-sequence/sdk/package/dist/esm/EventEmitter.js
deleted file mode 100644
index 3e651dd..0000000
--- a/G102-sequence/sdk/package/dist/esm/EventEmitter.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Game Iframe SDK - Event Emitter
- * Simple typed event emitter for SDK
- */
-export class EventEmitter {
- constructor() {
- this.handlers = new Map();
- }
- /**
- * Subscribe to an event
- */
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- // Return unsubscribe function
- return () => this.off(event, handler);
- }
- /**
- * Subscribe to an event (once)
- */
- once(event, handler) {
- const wrappedHandler = (data) => {
- this.off(event, wrappedHandler);
- handler(data);
- };
- return this.on(event, wrappedHandler);
- }
- /**
- * Unsubscribe from an event
- */
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- /**
- * Emit an event
- */
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- console.error(`[EventEmitter] Error in handler for "${String(event)}":`, err);
- }
- });
- }
- /**
- * Remove all handlers for an event (or all events)
- */
- removeAllListeners(event) {
- if (event) {
- this.handlers.delete(event);
- }
- else {
- this.handlers.clear();
- }
- }
-}
-//# sourceMappingURL=EventEmitter.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/EventEmitter.js.map b/G102-sequence/sdk/package/dist/esm/EventEmitter.js.map
deleted file mode 100644
index 06af93a..0000000
--- a/G102-sequence/sdk/package/dist/esm/EventEmitter.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"EventEmitter.js","sourceRoot":"","sources":["../../src/EventEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,YAAY;IAAzB;QACY,aAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;IAwDvE,CAAC;IAtDG;;OAEG;IACH,EAAE,CAAyB,KAAQ,EAAE,OAAgC;QACjE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEvC,8BAA8B;QAC9B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,IAAI,CAAyB,KAAQ,EAAE,OAAgC;QACnE,MAAM,cAAc,GAAG,CAAC,IAAe,EAAE,EAAE;YACvC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,GAAG,CAAyB,KAAQ,EAAE,OAAgC;QAClE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAI,CAAyB,KAAQ,EAAE,IAAe;QAClD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;YACxC,IAAI,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,wCAAwC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAClF,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,KAAoB;QACnC,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACL,CAAC;CACJ"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js b/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js
deleted file mode 100644
index 16cfa31..0000000
--- a/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/**
- * Game Iframe SDK - Core
- * SDK chính - compose các layers: MessageHandler, MessageSender
- */
-import { EventEmitter } from './EventEmitter';
-import { MessageHandler } from './MessageHandler';
-import { MessageSender } from './MessageSender';
-import { DEFAULT_CONFIG, } from './types';
-/**
- * GameIframeSDK - Main SDK class
- * Composes MessageHandler và MessageSender
- */
-export class GameIframeSDK extends EventEmitter {
- constructor(config) {
- super();
- this.pendingData = null;
- this.isReady = false;
- this.config = { ...DEFAULT_CONFIG, ...config };
- // Initialize layers
- this.messageHandler = new MessageHandler({
- acceptedOrigin: this.config.iframeOrigin,
- debug: this.config.debug,
- });
- this.messageSender = new MessageSender({
- targetOrigin: this.config.iframeOrigin,
- debug: this.config.debug,
- });
- // Setup event forwarding
- this.setupEventForwarding();
- // Start listening
- this.messageHandler.start();
- this.log('info', 'SDK initialized', { config: this.config });
- }
- // ==========================================================================
- // PUBLIC API - Iframe Management
- // ==========================================================================
- /**
- * Set iframe element reference
- */
- setIframe(iframe) {
- this.messageSender.setIframe(iframe);
- this.isReady = false;
- this.log('info', 'Iframe set', { hasIframe: !!iframe });
- return this;
- }
- /**
- * Get current iframe
- */
- getIframe() {
- return this.messageSender.getIframe();
- }
- /**
- * Check if game is ready
- */
- isGameReady() {
- return this.isReady;
- }
- /**
- * Check if sender is ready (iframe available)
- */
- isSenderReady() {
- return this.messageSender.isReady();
- }
- // ==========================================================================
- // PUBLIC API - Send Data
- // ==========================================================================
- /**
- * Send game data to iframe
- */
- sendGameData(data) {
- const result = this.messageSender.sendGameData(data);
- if (!result.success) {
- this.emit('error', {
- message: 'Failed to send game data',
- error: result.error,
- });
- }
- return result.success;
- }
- /**
- * Send leaderboard data to iframe
- */
- sendLeaderboard(data) {
- const result = this.messageSender.sendLeaderboard(data);
- if (!result.success) {
- this.emit('error', {
- message: 'Failed to send leaderboard',
- error: result.error,
- });
- }
- return result.success;
- }
- // ==========================================================================
- // PUBLIC API - Queue & Auto-send
- // ==========================================================================
- /**
- * Queue data to be sent when game is ready
- */
- queueGameData(data) {
- this.pendingData = data;
- this.log('info', 'Data queued for when game is ready');
- // If already ready, send immediately
- if (this.isReady) {
- this.sendQueuedData();
- }
- return this;
- }
- /**
- * Clear queued data
- */
- clearQueuedData() {
- this.pendingData = null;
- return this;
- }
- // ==========================================================================
- // PUBLIC API - Iframe Control
- // ==========================================================================
- /**
- * Force reload iframe
- */
- reloadIframe() {
- this.isReady = false;
- return this.messageSender.reloadIframe();
- }
- // ==========================================================================
- // PUBLIC API - Lifecycle
- // ==========================================================================
- /**
- * Cleanup and destroy SDK
- */
- destroy() {
- this.messageHandler.destroy();
- this.removeAllListeners();
- this.pendingData = null;
- this.isReady = false;
- this.log('info', 'SDK destroyed');
- }
- // ==========================================================================
- // PUBLIC API - Direct Layer Access (Advanced)
- // ==========================================================================
- /**
- * Get MessageHandler instance for advanced usage
- */
- getMessageHandler() {
- return this.messageHandler;
- }
- /**
- * Get MessageSender instance for advanced usage
- */
- getMessageSender() {
- return this.messageSender;
- }
- // ==========================================================================
- // PRIVATE METHODS
- // ==========================================================================
- /**
- * Setup event forwarding from MessageHandler to SDK events
- */
- setupEventForwarding() {
- // Forward gameReady
- this.messageHandler.on('gameReady', () => {
- this.isReady = true;
- this.emit('gameReady', undefined);
- // Auto-send queued data if enabled
- if (this.config.autoSendOnReady && this.pendingData) {
- setTimeout(() => {
- this.sendQueuedData();
- }, this.config.readyDelay);
- }
- });
- // Forward answerReport
- this.messageHandler.on('answerReport', (data) => {
- this.emit('answerReport', data);
- });
- // Forward finalResult
- this.messageHandler.on('finalResult', (data) => {
- this.emit('finalResult', data);
- });
- // Forward leaderboardRequest
- this.messageHandler.on('leaderboardRequest', (data) => {
- this.emit('leaderboardRequest', data);
- });
- // Forward errors
- this.messageHandler.on('error', (error) => {
- this.emit('error', error);
- });
- }
- /**
- * Send queued data
- */
- sendQueuedData() {
- if (this.pendingData) {
- this.sendGameData(this.pendingData);
- this.pendingData = null;
- }
- }
- /**
- * Internal logging
- */
- log(level, message, data) {
- if (this.config.debug) {
- const prefix = '[GameIframeSDK]';
- switch (level) {
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
- this.emit('log', { level, message, data });
- }
-}
-// ==========================================================================
-// FACTORY / SINGLETON HELPERS
-// ==========================================================================
-let defaultInstance = null;
-/**
- * Create SDK instance
- */
-export function createGameIframeSDK(config) {
- return new GameIframeSDK(config);
-}
-/**
- * Get or create default SDK instance
- */
-export function getGameIframeSDK(config) {
- if (!defaultInstance && config) {
- defaultInstance = new GameIframeSDK(config);
- }
- if (!defaultInstance) {
- throw new Error('GameIframeSDK not initialized. Call with config first.');
- }
- return defaultInstance;
-}
-/**
- * Destroy default instance
- */
-export function destroyGameIframeSDK() {
- defaultInstance?.destroy();
- defaultInstance = null;
-}
-//# sourceMappingURL=GameIframeSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js.map b/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js.map
deleted file mode 100644
index 47416a3..0000000
--- a/G102-sequence/sdk/package/dist/esm/GameIframeSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameIframeSDK.js","sourceRoot":"","sources":["../../src/GameIframeSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/MessageHandler.js b/G102-sequence/sdk/package/dist/esm/MessageHandler.js
deleted file mode 100644
index 7700394..0000000
--- a/G102-sequence/sdk/package/dist/esm/MessageHandler.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Game Iframe SDK - Message Handler
- * Xử lý message từ iframe
- */
-import { MESSAGE_TYPES } from './types';
-import { EventEmitter } from './EventEmitter';
-/**
- * MessageHandler - Xử lý incoming messages từ iframe
- */
-export class MessageHandler extends EventEmitter {
- constructor(config) {
- super();
- this.boundHandler = null;
- this.isListening = false;
- this.config = config;
- }
- /**
- * Start listening for messages
- */
- start() {
- if (this.isListening) {
- return this;
- }
- this.boundHandler = this.handleMessage.bind(this);
- window.addEventListener('message', this.boundHandler);
- this.isListening = true;
- this.log('MessageHandler started');
- return this;
- }
- /**
- * Stop listening for messages
- */
- stop() {
- if (this.boundHandler) {
- window.removeEventListener('message', this.boundHandler);
- this.boundHandler = null;
- }
- this.isListening = false;
- this.log('MessageHandler stopped');
- return this;
- }
- /**
- * Check if handler is listening
- */
- isActive() {
- return this.isListening;
- }
- /**
- * Handle incoming message
- */
- handleMessage(event) {
- // Origin check
- if (!this.isOriginAllowed(event.origin)) {
- return;
- }
- const { type, data } = event.data || {};
- if (!type)
- return;
- this.log(`Received: ${type}`, data);
- try {
- switch (type) {
- case MESSAGE_TYPES.GAME_READY:
- this.emit('gameReady', undefined);
- break;
- case MESSAGE_TYPES.ANSWER_REPORT:
- // Raw data pass-through
- this.emit('answerReport', data);
- break;
- case MESSAGE_TYPES.FINAL_RESULT:
- // Raw data pass-through
- this.emit('finalResult', data);
- break;
- case MESSAGE_TYPES.GET_LEADERBOARD:
- this.emit('leaderboardRequest', { top: data?.top || 10 });
- break;
- default:
- this.emit('unknownMessage', { type, data });
- break;
- }
- }
- catch (error) {
- const err = error;
- this.emit('error', { message: `Error handling ${type}`, error: err });
- }
- }
- /**
- * Check if origin is allowed
- */
- isOriginAllowed(origin) {
- if (this.config.acceptedOrigin === '*') {
- return true;
- }
- return origin === this.config.acceptedOrigin;
- }
- /**
- * Debug log
- */
- log(message, data) {
- if (this.config.debug) {
- console.log('[MessageHandler]', message, data ?? '');
- }
- }
- /**
- * Cleanup
- */
- destroy() {
- this.stop();
- this.removeAllListeners();
- }
-}
-//# sourceMappingURL=MessageHandler.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/MessageHandler.js.map b/G102-sequence/sdk/package/dist/esm/MessageHandler.js.map
deleted file mode 100644
index 8800b58..0000000
--- a/G102-sequence/sdk/package/dist/esm/MessageHandler.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../src/MessageHandler.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/MessageSender.js b/G102-sequence/sdk/package/dist/esm/MessageSender.js
deleted file mode 100644
index e30199c..0000000
--- a/G102-sequence/sdk/package/dist/esm/MessageSender.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Game Iframe SDK - Message Sender
- * Gửi message đến iframe
- */
-import { MESSAGE_TYPES } from './types';
-/**
- * MessageSender - Gửi messages đến iframe
- */
-export class MessageSender {
- constructor(config) {
- this.iframe = null;
- this.config = config;
- }
- /**
- * Set iframe element
- */
- setIframe(iframe) {
- this.iframe = iframe;
- return this;
- }
- /**
- * Get current iframe
- */
- getIframe() {
- return this.iframe;
- }
- /**
- * Check if iframe is available
- */
- isReady() {
- return !!this.iframe?.contentWindow;
- }
- /**
- * Send raw message to iframe
- */
- sendRaw(message) {
- if (!this.iframe?.contentWindow) {
- return {
- success: false,
- error: new Error('Iframe not available'),
- };
- }
- try {
- this.iframe.contentWindow.postMessage(message, this.config.targetOrigin);
- this.log('Sent message', { type: message.type });
- return { success: true };
- }
- catch (error) {
- const err = error;
- this.log('Send failed', { error: err.message });
- return { success: false, error: err };
- }
- }
- /**
- * Send game data (SERVER_PUSH_DATA)
- */
- sendGameData(payload) {
- // Inline message creation
- const message = {
- type: MESSAGE_TYPES.SERVER_PUSH_DATA,
- jsonData: payload,
- };
- const result = this.sendRaw(message);
- if (result.success) {
- const dataLength = payload.data?.length || 0;
- this.log('Sent game data', {
- game_id: payload.game_id,
- items: dataLength,
- });
- }
- return result;
- }
- /**
- * Send leaderboard (SERVER_PUSH_LEADERBOARD)
- */
- sendLeaderboard(data) {
- // Inline message creation
- const message = {
- type: MESSAGE_TYPES.SERVER_PUSH_LEADERBOARD,
- leaderboardData: data,
- };
- const result = this.sendRaw(message);
- if (result.success) {
- this.log('Sent leaderboard', {
- players: data.top_players?.length || 0,
- hasUserRank: !!data.user_rank,
- });
- }
- return result;
- }
- /**
- * Reload iframe
- */
- reloadIframe() {
- if (!this.iframe) {
- return false;
- }
- const currentSrc = this.iframe.src;
- if (!currentSrc || currentSrc === 'about:blank') {
- return false;
- }
- this.iframe.src = '';
- setTimeout(() => {
- if (this.iframe) {
- this.iframe.src = currentSrc;
- this.log('Iframe reloaded');
- }
- }, 100);
- return true;
- }
- /**
- * Debug log
- */
- log(message, data) {
- if (this.config.debug) {
- console.log('[MessageSender]', message);
- if (data) {
- try {
- console.log(JSON.stringify(data, null, 2));
- }
- catch (e) {
- console.log(data);
- }
- }
- }
- }
-}
-//# sourceMappingURL=MessageSender.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/MessageSender.js.map b/G102-sequence/sdk/package/dist/esm/MessageSender.js.map
deleted file mode 100644
index 8993a62..0000000
--- a/G102-sequence/sdk/package/dist/esm/MessageSender.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MessageSender.js","sourceRoot":"","sources":["../../src/MessageSender.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/DataValidator.js b/G102-sequence/sdk/package/dist/esm/client/DataValidator.js
deleted file mode 100644
index 8a4fb75..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/DataValidator.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * Data Validator
- * Verify data structure cho từng game code
- *
- * Usage:
- * ```typescript
- * import { validateGameData, DataValidator } from 'game-iframe-sdk/client';
- *
- * const result = validateGameData('G001', receivedData);
- * if (!result.valid) {
- * console.error('Invalid data:', result.errors);
- * }
- * ```
- */
-import { GAME_CODES } from '../kit/GameDataHandler';
-// =============================================================================
-// SCHEMAS FOR EACH GAME CODE
-// =============================================================================
-const QUIZ_BASE_SCHEMA = {
- id: { type: 'string', required: true, description: 'Unique question ID' },
- options: { type: 'array', required: true, arrayItemType: 'string', description: 'Answer options' },
- answer: { type: 'number', required: true, description: 'Correct answer index (0-based)' },
-};
-const SCHEMAS = {
- // Quiz variants
- G001: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- },
- G002: {
- ...QUIZ_BASE_SCHEMA,
- question_audio: { type: 'string', required: true, description: 'Audio URL for question' },
- },
- G003: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- // options are audio URLs
- },
- G004: {
- ...QUIZ_BASE_SCHEMA,
- question_image: { type: 'string', required: true, description: 'Image URL for question' },
- question: { type: 'string', required: false, description: 'Optional text hint' },
- },
- // G005: Quiz Text-Image (options are image URLs, client picks index)
- G005: {
- ...QUIZ_BASE_SCHEMA,
- question: { type: 'string', required: true, description: 'Text question' },
- // options are image URLs, answer is index pointing to correct image
- },
- // Sequence Word variants
- G110: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true, description: 'The word to arrange' },
- parts: { type: 'array', required: true, arrayItemType: 'string', description: 'Letters/parts to arrange' },
- answer: { type: 'array', required: true, arrayItemType: 'string', description: 'Correct order' },
- },
- G111: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true, description: 'Audio hint URL' },
- },
- G112: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G113: {
- id: { type: 'string', required: true },
- word: { type: 'string', required: true },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- // Sequence Sentence variants
- G120: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false, description: 'Full sentence (hint)' },
- parts: { type: 'array', required: true, arrayItemType: 'string', description: 'Words to arrange' },
- answer: { type: 'array', required: true, arrayItemType: 'string', description: 'Correct word order' },
- },
- G121: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G122: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- },
- G123: {
- id: { type: 'string', required: true },
- sentence: { type: 'string', required: false },
- parts: { type: 'array', required: true, arrayItemType: 'string' },
- answer: { type: 'array', required: true, arrayItemType: 'string' },
- audio_url: { type: 'string', required: true },
- }
-};
-// =============================================================================
-// VALIDATOR
-// =============================================================================
-/**
- * Validate a single item against schema
- */
-function validateItem(item, schema, itemIndex) {
- const errors = [];
- if (!item || typeof item !== 'object') {
- errors.push(`Item [${itemIndex}]: Must be an object`);
- return errors;
- }
- for (const [field, fieldSchema] of Object.entries(schema)) {
- const value = item[field];
- // Check required
- if (fieldSchema.required && (value === undefined || value === null)) {
- errors.push(`Item [${itemIndex}].${field}: Required field is missing`);
- continue;
- }
- // Skip validation if optional and not present
- if (!fieldSchema.required && (value === undefined || value === null)) {
- continue;
- }
- // Check type
- const actualType = Array.isArray(value) ? 'array' : typeof value;
- if (fieldSchema.type !== 'any' && actualType !== fieldSchema.type) {
- errors.push(`Item [${itemIndex}].${field}: Expected ${fieldSchema.type}, got ${actualType}`);
- continue;
- }
- // Check array items
- if (fieldSchema.type === 'array' && fieldSchema.arrayItemType && fieldSchema.arrayItemType !== 'any') {
- for (let i = 0; i < value.length; i++) {
- const itemType = typeof value[i];
- if (itemType !== fieldSchema.arrayItemType) {
- errors.push(`Item [${itemIndex}].${field}[${i}]: Expected ${fieldSchema.arrayItemType}, got ${itemType}`);
- }
- }
- }
- }
- return errors;
-}
-/**
- * Validate game data payload
- */
-export function validateGameData(gameCode, payload) {
- const errors = [];
- const warnings = [];
- // Check game code
- if (!GAME_CODES[gameCode]) {
- errors.push(`Unknown game code: ${gameCode}`);
- return { valid: false, errors, warnings };
- }
- // Check payload structure
- if (!payload || typeof payload !== 'object') {
- errors.push('Payload must be an object');
- return { valid: false, errors, warnings };
- }
- // Check data array
- const items = payload.data || payload.items || payload.questions;
- if (!items) {
- errors.push('Missing data array (expected "data", "items", or "questions")');
- return { valid: false, errors, warnings };
- }
- if (!Array.isArray(items)) {
- errors.push('"data" must be an array');
- return { valid: false, errors, warnings };
- }
- if (items.length === 0) {
- warnings.push('Data array is empty');
- }
- // Validate each item
- const schema = SCHEMAS[gameCode];
- for (let i = 0; i < items.length; i++) {
- const itemErrors = validateItem(items[i], schema, i);
- errors.push(...itemErrors);
- }
- // Check for duplicate IDs
- const ids = items.map((item) => item.id).filter(Boolean);
- const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
- if (duplicates.length > 0) {
- warnings.push(`Duplicate IDs found: ${[...new Set(duplicates)].join(', ')}`);
- }
- return {
- valid: errors.length === 0,
- errors,
- warnings,
- };
-}
-/**
- * Get schema for a game code
- */
-export function getSchema(gameCode) {
- return SCHEMAS[gameCode] ?? null;
-}
-/**
- * Get schema documentation for a game code
- */
-export function getSchemaDoc(gameCode) {
- const schema = SCHEMAS[gameCode];
- if (!schema)
- return `Unknown game code: ${gameCode}`;
- const gameInfo = GAME_CODES[gameCode];
- const lines = [
- `## ${gameCode}: ${gameInfo.name}`,
- `Category: ${gameInfo.category}`,
- '',
- '### Fields:',
- ];
- for (const [field, fieldSchema] of Object.entries(schema)) {
- const required = fieldSchema.required ? '(required)' : '(optional)';
- let type = fieldSchema.type;
- if (fieldSchema.arrayItemType) {
- type = `${fieldSchema.type}<${fieldSchema.arrayItemType}>`;
- }
- lines.push(`- **${field}**: ${type} ${required}`);
- if (fieldSchema.description) {
- lines.push(` - ${fieldSchema.description}`);
- }
- }
- return lines.join('\n');
-}
-// =============================================================================
-// DATA VALIDATOR CLASS
-// =============================================================================
-export class DataValidator {
- constructor(gameCode) {
- this.gameCode = gameCode;
- }
- validate(payload) {
- return validateGameData(this.gameCode, payload);
- }
- getSchema() {
- return getSchema(this.gameCode);
- }
- getSchemaDoc() {
- return getSchemaDoc(this.gameCode);
- }
-}
-//# sourceMappingURL=DataValidator.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/DataValidator.js.map b/G102-sequence/sdk/package/dist/esm/client/DataValidator.js.map
deleted file mode 100644
index 46e14cd..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/DataValidator.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"DataValidator.js","sourceRoot":"","sources":["../../../src/client/DataValidator.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js b/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js
deleted file mode 100644
index 2a9593e..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * GameClientSDK - SDK dành cho Game Iframe
- *
- * Sử dụng trong game để:
- * - Tự động xác định mode (preview/live) từ URL
- * - Nhận data từ parent (preview) hoặc fetch API (live)
- * - Verify answers locally
- * - Report results về parent
- */
-import { checkAnswer, sanitizeForClient, GAME_CODES } from '../kit/GameDataHandler';
-import { getMockData } from './MockData';
-import { validateGameData } from './DataValidator';
-class SimpleEventEmitter {
- constructor() {
- this.handlers = new Map();
- }
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- return () => this.off(event, handler);
- }
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- console.error(`[GameClientSDK] Error in ${String(event)} handler:`, err);
- }
- });
- }
-}
-// =============================================================================
-// GAME CLIENT SDK
-// =============================================================================
-export class GameClientSDK extends SimpleEventEmitter {
- constructor(config = {}) {
- super();
- // Data storage
- this.originalItems = new Map(); // Có đáp án
- this.sanitizedItems = []; // Không có đáp án
- this.userAnswers = new Map();
- this.isInitialized = false;
- this.startTime = 0;
- this.config = {
- debug: config.debug ?? false,
- apiBaseUrl: config.apiBaseUrl ?? '',
- getAuthHeaders: config.getAuthHeaders ?? (() => ({})),
- };
- // Parse URL params
- this.params = this.parseURLParams();
- this.mode = this.params.mode;
- this.log('info', 'SDK created', { mode: this.mode, params: this.params });
- // Emit mode detected
- this.emit('modeDetected', { mode: this.mode, params: this.params });
- // Setup message listener
- this.setupMessageListener();
- // Auto-initialize based on mode
- this.initialize();
- }
- // ==========================================================================
- // PUBLIC API
- // ==========================================================================
- /**
- * Get current mode
- */
- getMode() {
- return this.mode;
- }
- /**
- * Get URL params
- */
- getParams() {
- return { ...this.params };
- }
- /**
- * Get game code
- */
- getGameCode() {
- return this.params.gameCode;
- }
- /**
- * Get sanitized items (safe for rendering)
- */
- getItems() {
- return this.sanitizedItems;
- }
- /**
- * Submit an answer and get verification result
- */
- submitAnswer(questionId, choice) {
- const originalItem = this.originalItems.get(questionId);
- if (!originalItem) {
- this.log('warn', `Item not found: ${questionId}`);
- return { isCorrect: false, score: 0, feedback: 'Question not found' };
- }
- // Verify using GameDataHandler
- const result = checkAnswer(this.params.gameCode, originalItem, choice);
- // Store user answer
- const timeSpent = Date.now() - (this.userAnswers.size === 0 ? this.startTime : Date.now());
- this.userAnswers.set(questionId, {
- choice,
- result: result.isCorrect ? 1 : 0,
- time: timeSpent,
- });
- // Report to parent
- this.sendAnswerReport(questionId, choice, result.isCorrect ? 1 : 0, timeSpent);
- this.log('info', `Answer submitted: ${questionId}`, { choice, result });
- return result;
- }
- /**
- * Get final result
- */
- getFinalResult() {
- const details = Array.from(this.userAnswers.entries()).map(([id, data]) => ({
- question_id: id,
- choice: data.choice,
- result: data.result,
- time_spent: data.time,
- }));
- const correct = details.filter(d => d.result === 1).length;
- const total = this.originalItems.size;
- return {
- score: total > 0 ? Math.round((correct / total) * 100) : 0,
- total,
- correct,
- wrong: total - correct,
- details,
- };
- }
- /**
- * Report final result to parent
- */
- reportFinalResult(result) {
- const finalResult = result ?? this.getFinalResult();
- window.parent.postMessage({
- type: 'FINAL_RESULT',
- data: finalResult,
- }, '*');
- this.log('info', 'Final result reported', finalResult);
- }
- /**
- * Request leaderboard from parent
- */
- requestLeaderboard(top = 10) {
- window.parent.postMessage({
- type: 'GET_LEADERBOARD',
- data: { top },
- }, '*');
- }
- /**
- * Cleanup
- */
- destroy() {
- window.removeEventListener('message', this.handleMessage);
- this.originalItems.clear();
- this.sanitizedItems = [];
- this.userAnswers.clear();
- this.log('info', 'SDK destroyed');
- }
- // ==========================================================================
- // PRIVATE METHODS
- // ==========================================================================
- parseURLParams() {
- const searchParams = new URLSearchParams(window.location.search);
- const mode = (searchParams.get('mode') || 'preview');
- const gameCode = (searchParams.get('game_code') || 'G001');
- const gameId = searchParams.get('game_id') || undefined;
- const lid = searchParams.get('lid') || undefined;
- const studentId = searchParams.get('student_id') || undefined;
- // Validate mode
- if (mode !== 'preview' && mode !== 'live' && mode !== 'dev') {
- this.log('warn', `Invalid mode: ${mode}, defaulting to preview`);
- }
- // Validate game code
- if (!GAME_CODES[gameCode]) {
- this.log('warn', `Unknown game code: ${gameCode}`);
- }
- return { mode, gameCode, gameId, lid, studentId };
- }
- setupMessageListener() {
- this.handleMessage = this.handleMessage.bind(this);
- window.addEventListener('message', this.handleMessage);
- }
- handleMessage(event) {
- const { type, jsonData, leaderboardData } = event.data || {};
- this.log('debug', 'Message received', { type, hasData: !!jsonData });
- switch (type) {
- case 'SERVER_PUSH_DATA':
- if (jsonData) {
- this.handleDataReceived(jsonData);
- }
- break;
- case 'SERVER_PUSH_LEADERBOARD':
- if (leaderboardData) {
- this.log('info', 'Leaderboard received', leaderboardData);
- // Could emit event here
- }
- break;
- }
- }
- async initialize() {
- // Send GAME_READY immediately
- this.sendGameReady();
- if (this.mode === 'dev') {
- // Dev mode: load mock data immediately
- this.log('info', 'DEV MODE: Loading mock data...');
- this.loadMockData();
- }
- else if (this.mode === 'live') {
- // Live mode: fetch data from API
- await this.fetchLiveData();
- }
- else {
- // Preview mode: wait for postMessage
- this.log('info', 'Preview mode: waiting for SERVER_PUSH_DATA...');
- }
- }
- /**
- * Load mock data for dev mode
- */
- loadMockData() {
- const mockData = getMockData(this.params.gameCode);
- if (!mockData) {
- this.emit('error', {
- message: `No mock data available for game code: ${this.params.gameCode}`
- });
- return;
- }
- this.log('info', `Loaded mock data for ${this.params.gameCode}`);
- this.handleDataReceived(mockData);
- }
- sendGameReady() {
- window.parent.postMessage({ type: 'GAME_READY' }, '*');
- this.emit('ready', undefined);
- this.log('info', 'GAME_READY sent');
- }
- async fetchLiveData() {
- const { gameId, lid } = this.params;
- if (!gameId || !lid) {
- this.emit('error', { message: 'Live mode requires game_id and lid' });
- return;
- }
- if (!this.config.apiBaseUrl) {
- this.emit('error', { message: 'Live mode requires apiBaseUrl' });
- return;
- }
- try {
- const url = `${this.config.apiBaseUrl}/games/${gameId}?lid=${lid}`;
- const headers = {
- 'Content-Type': 'application/json',
- ...this.config.getAuthHeaders(),
- };
- this.log('info', `Fetching live data: ${url}`);
- const response = await fetch(url, { headers });
- if (!response.ok) {
- throw new Error(`API Error: ${response.status}`);
- }
- const data = await response.json();
- this.handleDataReceived(data);
- }
- catch (error) {
- this.log('error', 'Failed to fetch live data', error);
- this.emit('error', { message: 'Failed to fetch game data', error });
- }
- }
- handleDataReceived(payload) {
- this.startTime = Date.now();
- // Update game code if provided
- if (payload.game_code && GAME_CODES[payload.game_code]) {
- this.params.gameCode = payload.game_code;
- }
- // Validate data structure
- const validation = validateGameData(this.params.gameCode, payload);
- if (!validation.valid) {
- this.log('error', 'Data validation failed', validation.errors);
- this.emit('validationError', { validation });
- // Continue anyway to allow partial rendering
- }
- if (validation.warnings.length > 0) {
- this.log('warn', 'Data validation warnings', validation.warnings);
- }
- // Extract items from various payload formats
- const items = payload.data || payload.items || payload.questions || [];
- const resumeData = payload.completed_question_ids || [];
- // Store original items (with answers)
- this.originalItems.clear();
- items.forEach((item) => {
- if (item.id) {
- this.originalItems.set(item.id, item);
- }
- });
- // Sanitize for client (remove answers)
- this.sanitizedItems = sanitizeForClient(this.params.gameCode, items);
- this.isInitialized = true;
- this.log('info', `Data received: ${items.length} items, ${resumeData.length} completed`);
- // Emit event with validation result
- this.emit('dataReceived', {
- items: this.sanitizedItems,
- resumeData,
- validation,
- });
- }
- sendAnswerReport(questionId, choice, result, timeSpent) {
- window.parent.postMessage({
- type: 'ANSWER_REPORT',
- data: {
- question_id: questionId,
- question_index: Array.from(this.originalItems.keys()).indexOf(questionId),
- choice,
- result,
- time_spent: timeSpent,
- },
- }, '*');
- }
- log(level, message, data) {
- if (!this.config.debug && level === 'debug')
- return;
- const prefix = `[GameClientSDK:${this.mode}]`;
- switch (level) {
- case 'debug':
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
-}
-// =============================================================================
-// FACTORY
-// =============================================================================
-let clientInstance = null;
-/**
- * Get or create GameClientSDK instance
- */
-export function getGameClientSDK(config) {
- if (!clientInstance) {
- clientInstance = new GameClientSDK(config);
- }
- return clientInstance;
-}
-/**
- * Destroy client instance
- */
-export function destroyGameClientSDK() {
- clientInstance?.destroy();
- clientInstance = null;
-}
-//# sourceMappingURL=GameClientSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js.map b/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js.map
deleted file mode 100644
index 0585b09..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/GameClientSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameClientSDK.js","sourceRoot":"","sources":["../../../src/client/GameClientSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/MockData.js b/G102-sequence/sdk/package/dist/esm/client/MockData.js
deleted file mode 100644
index 6e5379c..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/MockData.js
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * Mock Data cho từng Game Code
- * Game developers dùng để test game standalone
- *
- * Usage:
- * ```typescript
- * import { MockData } from 'game-iframe-sdk/client';
- *
- * // Lấy sample data cho Quiz Text-Text
- * const quizData = MockData.G001;
- *
- * // Lấy sample data cho Sequence Word
- * const seqData = MockData.G110;
- * ```
- */
-// =============================================================================
-// QUIZ MOCK DATA
-// =============================================================================
-/** G001: Quiz Text-Text */
-export const MOCK_G001 = {
- game_code: 'G001',
- game_id: 'mock-quiz-text-text',
- data: [
- {
- id: 'q1',
- question: 'Thủ đô của Việt Nam là gì?',
- options: ['Hà Nội', 'Hồ Chí Minh', 'Đà Nẵng', 'Huế'],
- answer: 0, // Index của đáp án đúng
- },
- {
- id: 'q2',
- question: '2 + 2 = ?',
- options: ['3', '4', '5', '6'],
- answer: 1,
- },
- {
- id: 'q3',
- question: 'Con vật nào biết bay?',
- options: ['Chó', 'Mèo', 'Chim', 'Cá'],
- answer: 2,
- },
- ],
-};
-/** G002: Quiz Audio-Text */
-export const MOCK_G002 = {
- game_code: 'G002',
- game_id: 'mock-quiz-audio-text',
- data: [
- {
- id: 'q1',
- question_audio: 'https://example.com/audio/question1.mp3',
- options: ['Apple', 'Banana', 'Orange', 'Grape'],
- answer: 0,
- },
- {
- id: 'q2',
- question_audio: 'https://example.com/audio/question2.mp3',
- options: ['Dog', 'Cat', 'Bird', 'Fish'],
- answer: 2,
- },
- ],
-};
-/** G003: Quiz Text-Audio */
-export const MOCK_G003 = {
- game_code: 'G003',
- game_id: 'mock-quiz-text-audio',
- data: [
- {
- id: 'q1',
- question: 'Chọn phát âm đúng của từ "Hello"',
- options: [
- 'https://example.com/audio/hello1.mp3',
- 'https://example.com/audio/hello2.mp3',
- 'https://example.com/audio/hello3.mp3',
- ],
- answer: 0,
- },
- ],
-};
-/** G004: Quiz Image-Text */
-export const MOCK_G004 = {
- game_code: 'G004',
- game_id: 'mock-quiz-image-text',
- data: [
- {
- id: 'q1',
- question_image: 'https://example.com/images/apple.jpg',
- question: 'Đây là quả gì?', // Optional hint
- options: ['Táo', 'Cam', 'Chuối', 'Nho'],
- answer: 0,
- },
- {
- id: 'q2',
- question_image: 'https://example.com/images/cat.jpg',
- options: ['Chó', 'Mèo', 'Thỏ', 'Chuột'],
- answer: 1,
- },
- ],
-};
-/** G005: Quiz Text-Image */
-export const MOCK_G005 = {
- game_code: 'G005',
- game_id: 'mock-quiz-text-image',
- data: [
- {
- id: 'q1',
- question: 'Chọn hình ảnh con mèo',
- options: [
- 'https://example.com/images/dog.jpg',
- 'https://example.com/images/cat.jpg',
- 'https://example.com/images/bird.jpg',
- ],
- answer: 1,
- },
- ],
-};
-// =============================================================================
-// SEQUENCE WORD MOCK DATA
-// =============================================================================
-/** G110: Sequence Word - no audio */
-export const MOCK_G110 = {
- game_code: 'G110',
- game_id: 'mock-sequence-word',
- data: [
- {
- id: 'sw1',
- word: 'APPLE',
- parts: ['A', 'P', 'P', 'L', 'E'], // Đáp án đúng theo thứ tự
- answer: ['A', 'P', 'P', 'L', 'E'], // SDK sẽ shuffle parts, giữ answer để verify
- },
- {
- id: 'sw2',
- word: 'HELLO',
- parts: ['H', 'E', 'L', 'L', 'O'],
- answer: ['H', 'E', 'L', 'L', 'O'],
- },
- {
- id: 'sw3',
- word: 'WORLD',
- parts: ['W', 'O', 'R', 'L', 'D'],
- answer: ['W', 'O', 'R', 'L', 'D'],
- },
- ],
-};
-/** G111: Sequence Word - audio, hide 2 */
-export const MOCK_G111 = {
- game_code: 'G111',
- game_id: 'mock-sequence-word-audio-2',
- data: [
- {
- id: 'sw1',
- word: 'BANANA',
- parts: ['B', 'A', 'N', 'A', 'N', 'A'],
- answer: ['B', 'A', 'N', 'A', 'N', 'A'],
- audio_url: 'https://example.com/audio/banana.mp3',
- },
- ],
-};
-/** G112: Sequence Word - audio, hide 4 */
-export const MOCK_G112 = {
- game_code: 'G112',
- game_id: 'mock-sequence-word-audio-4',
- data: [
- {
- id: 'sw1',
- word: 'COMPUTER',
- parts: ['C', 'O', 'M', 'P', 'U', 'T', 'E', 'R'],
- answer: ['C', 'O', 'M', 'P', 'U', 'T', 'E', 'R'],
- audio_url: 'https://example.com/audio/computer.mp3',
- },
- ],
-};
-/** G113: Sequence Word - audio, hide all */
-export const MOCK_G113 = {
- game_code: 'G113',
- game_id: 'mock-sequence-word-audio-all',
- data: [
- {
- id: 'sw1',
- word: 'ELEPHANT',
- parts: ['E', 'L', 'E', 'P', 'H', 'A', 'N', 'T'],
- answer: ['E', 'L', 'E', 'P', 'H', 'A', 'N', 'T'],
- audio_url: 'https://example.com/audio/elephant.mp3',
- },
- ],
-};
-// =============================================================================
-// SEQUENCE SENTENCE MOCK DATA
-// =============================================================================
-/** G120: Sequence Sentence - no audio */
-export const MOCK_G120 = {
- game_code: 'G120',
- game_id: 'mock-sequence-sentence',
- data: [
- {
- id: 'ss1',
- sentence: 'I love learning English.',
- parts: ['I', 'love', 'learning', 'English.'],
- answer: ['I', 'love', 'learning', 'English.'],
- },
- {
- id: 'ss2',
- sentence: 'The cat is sleeping.',
- parts: ['The', 'cat', 'is', 'sleeping.'],
- answer: ['The', 'cat', 'is', 'sleeping.'],
- },
- ],
-};
-/** G121: Sequence Sentence - audio, hide 2 */
-export const MOCK_G121 = {
- game_code: 'G121',
- game_id: 'mock-sequence-sentence-audio-2',
- data: [
- {
- id: 'ss1',
- sentence: 'She goes to school every day.',
- parts: ['She', 'goes', 'to', 'school', 'every', 'day.'],
- answer: ['She', 'goes', 'to', 'school', 'every', 'day.'],
- audio_url: 'https://example.com/audio/sentence1.mp3',
- },
- ],
-};
-/** G122: Sequence Sentence - audio, hide 4 */
-export const MOCK_G122 = {
- game_code: 'G122',
- game_id: 'mock-sequence-sentence-audio-4',
- data: [
- {
- id: 'ss1',
- sentence: 'My brother plays football in the park.',
- parts: ['My', 'brother', 'plays', 'football', 'in', 'the', 'park.'],
- answer: ['My', 'brother', 'plays', 'football', 'in', 'the', 'park.'],
- audio_url: 'https://example.com/audio/sentence2.mp3',
- },
- ],
-};
-/** G123: Sequence Sentence - audio, hide all */
-export const MOCK_G123 = {
- game_code: 'G123',
- game_id: 'mock-sequence-sentence-audio-all',
- data: [
- {
- id: 'ss1',
- sentence: 'The quick brown fox jumps over the lazy dog.',
- parts: ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog.'],
- answer: ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog.'],
- audio_url: 'https://example.com/audio/sentence3.mp3',
- },
- ],
-};
-// =============================================================================
-// MOCK DATA MAP
-// =============================================================================
-export const MockData = {
- // Quiz
- G001: MOCK_G001,
- G002: MOCK_G002,
- G003: MOCK_G003,
- G004: MOCK_G004,
- // Sequence Word
- G110: MOCK_G110,
- G111: MOCK_G111,
- G112: MOCK_G112,
- G113: MOCK_G113,
- // Sequence Sentence
- G120: MOCK_G120,
- G121: MOCK_G121,
- G122: MOCK_G122,
- G123: MOCK_G123,
- G005: MOCK_G005,
-};
-/**
- * Get mock data for a game code
- */
-export function getMockData(code) {
- return MockData[code] ?? null;
-}
-/**
- * Get all available game codes
- */
-export function getAvailableGameCodes() {
- return Object.keys(MockData);
-}
-//# sourceMappingURL=MockData.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/MockData.js.map b/G102-sequence/sdk/package/dist/esm/client/MockData.js.map
deleted file mode 100644
index 7bfcb60..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/MockData.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"MockData.js","sourceRoot":"","sources":["../../../src/client/MockData.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/index.js b/G102-sequence/sdk/package/dist/esm/client/index.js
deleted file mode 100644
index 4ade702..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Client SDK exports
- * SDK dành cho game developers sử dụng trong game iframe
- */
-export { GameClientSDK, getGameClientSDK, destroyGameClientSDK, } from './GameClientSDK';
-// Mock Data - sample data cho từng game code
-export { MockData, getMockData, getAvailableGameCodes, MOCK_G001, MOCK_G002, MOCK_G003, MOCK_G004, MOCK_G110, MOCK_G111, MOCK_G112, MOCK_G113, MOCK_G120, MOCK_G121, MOCK_G122, MOCK_G123, } from './MockData';
-// Data Validator - verify data structure
-export { validateGameData, getSchema, getSchemaDoc, DataValidator, } from './DataValidator';
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/client/index.js.map b/G102-sequence/sdk/package/dist/esm/client/index.js.map
deleted file mode 100644
index 9711281..0000000
--- a/G102-sequence/sdk/package/dist/esm/client/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GAQvB,MAAM,iBAAiB,CAAC;AAEzB,6CAA6C;AAC7C,OAAO,EACH,QAAQ,EACR,WAAW,EACX,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,GACZ,MAAM,YAAY,CAAC;AAEpB,yCAAyC;AACzC,OAAO,EACH,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,aAAa,GAIhB,MAAM,iBAAiB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js b/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js
deleted file mode 100644
index 7bc5276..0000000
--- a/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js
+++ /dev/null
@@ -1,292 +0,0 @@
-/**
- * Game Bridge
- * Wrapper đơn giản cho game developers để giao tiếp với SDK Iframe
- *
- * Usage:
- * ```typescript
- * import { GameBridge } from 'game-iframe-sdk/game-bridge';
- *
- * const bridge = new GameBridge({
- * sdkIframeUrl: 'https://sdk.sena.tech/sdk-iframe.html',
- * debug: true,
- * });
- *
- * // Init
- * await bridge.init({
- * mode: 'preview',
- * game_code: 'G001',
- * });
- *
- * // Listen for data
- * bridge.on('dataReady', (data) => {
- * renderGame(data.items);
- * });
- *
- * // Check answer
- * bridge.checkAnswer('q1', userChoice).then(result => {
- * showFeedback(result.correct);
- * });
- * ```
- */
-import { SDK_MESSAGE_TYPES, createSdkMessage, isSdkMessage, } from '../sdk-iframe/types';
-// =============================================================================
-// GAME BRIDGE
-// =============================================================================
-export class GameBridge {
- constructor(config) {
- this.sdkIframe = null;
- this.sdkOrigin = '';
- this.isReady = false;
- // Event handlers
- this.handlers = new Map();
- // Pending requests (for promise-based API)
- this.pendingRequests = new Map();
- this.requestCounter = 0;
- this.config = {
- sdkIframeUrl: config.sdkIframeUrl,
- debug: config.debug ?? false,
- timeout: config.timeout ?? 10000,
- };
- // Extract origin from SDK URL
- try {
- const url = new URL(this.config.sdkIframeUrl);
- this.sdkOrigin = url.origin;
- }
- catch {
- this.sdkOrigin = '*';
- }
- this.setupMessageListener();
- }
- // ==========================================================================
- // PUBLIC API - Init
- // ==========================================================================
- /**
- * Create SDK Iframe and initialize
- */
- async init(payload) {
- // Create hidden iframe
- this.sdkIframe = document.createElement('iframe');
- this.sdkIframe.src = this.config.sdkIframeUrl;
- this.sdkIframe.style.cssText = 'position:absolute;width:0;height:0;border:0;visibility:hidden;';
- this.sdkIframe.setAttribute('aria-hidden', 'true');
- document.body.appendChild(this.sdkIframe);
- this.log('info', 'SDK Iframe created');
- // Wait for iframe to load
- await new Promise((resolve) => {
- this.sdkIframe.onload = () => resolve();
- });
- // Send init
- return this.sendRequest(SDK_MESSAGE_TYPES.SDK_INIT, payload);
- }
- /**
- * Push data (preview mode)
- */
- async pushData(payload) {
- return this.sendRequest(SDK_MESSAGE_TYPES.SDK_PUSH_DATA, payload);
- }
- // ==========================================================================
- // PUBLIC API - Game Actions
- // ==========================================================================
- /**
- * Check answer - returns local result immediately
- * Also triggers server sync in background
- */
- async checkAnswer(questionId, choice, timeSpent) {
- const payload = {
- question_id: questionId,
- choice,
- time_spent: timeSpent,
- };
- return this.sendRequest(SDK_MESSAGE_TYPES.SDK_CHECK_ANSWER, payload);
- }
- /**
- * Get final result
- */
- async getFinalResult() {
- return this.sendRequest(SDK_MESSAGE_TYPES.SDK_GET_RESULT, {});
- }
- /**
- * Retry sync for a question
- */
- async retrySync(questionId) {
- return this.sendRequest(SDK_MESSAGE_TYPES.SDK_RETRY_SYNC, {
- question_id: questionId,
- });
- }
- // ==========================================================================
- // PUBLIC API - Events
- // ==========================================================================
- /**
- * Subscribe to events
- */
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- return () => this.off(event, handler);
- }
- /**
- * Unsubscribe from events
- */
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- // ==========================================================================
- // PUBLIC API - State
- // ==========================================================================
- /**
- * Check if SDK is ready
- */
- isSdkReady() {
- return this.isReady;
- }
- /**
- * Destroy bridge and cleanup
- */
- destroy() {
- // Clear pending requests
- this.pendingRequests.forEach((pending) => {
- clearTimeout(pending.timeout);
- pending.reject(new Error('Bridge destroyed'));
- });
- this.pendingRequests.clear();
- // Remove iframe
- if (this.sdkIframe && this.sdkIframe.parentNode) {
- this.sdkIframe.parentNode.removeChild(this.sdkIframe);
- }
- this.sdkIframe = null;
- // Clear handlers
- this.handlers.clear();
- this.log('info', 'Bridge destroyed');
- }
- // ==========================================================================
- // INTERNAL - Message Handling
- // ==========================================================================
- setupMessageListener() {
- window.addEventListener('message', this.handleMessage.bind(this));
- }
- handleMessage(event) {
- // Validate origin (if not *)
- if (this.sdkOrigin !== '*' && event.origin !== this.sdkOrigin) {
- return;
- }
- const data = event.data;
- if (!isSdkMessage(data)) {
- return;
- }
- this.log('debug', `Received: ${data.type}`, data.payload);
- // Handle pending request response
- if (data.request_id && this.pendingRequests.has(data.request_id)) {
- const pending = this.pendingRequests.get(data.request_id);
- clearTimeout(pending.timeout);
- this.pendingRequests.delete(data.request_id);
- if (data.type === SDK_MESSAGE_TYPES.SDK_ERROR) {
- pending.reject(data.payload);
- }
- else {
- pending.resolve(data.payload);
- }
- return;
- }
- // Handle events
- switch (data.type) {
- case SDK_MESSAGE_TYPES.SDK_READY:
- this.isReady = true;
- this.emit('ready', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_DATA_READY:
- this.emit('dataReady', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT:
- this.emit('answerResult', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_SYNC_STATUS:
- this.emit('syncStatus', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_SYNC_ERROR:
- this.emit('syncError', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_FINAL_RESULT:
- this.emit('finalResult', data.payload);
- break;
- case SDK_MESSAGE_TYPES.SDK_ERROR:
- this.emit('error', data.payload);
- break;
- }
- }
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- this.log('error', `Error in ${event} handler`, err);
- }
- });
- }
- // ==========================================================================
- // INTERNAL - Sending Messages
- // ==========================================================================
- sendRequest(type, payload) {
- return new Promise((resolve, reject) => {
- if (!this.sdkIframe?.contentWindow) {
- reject(new Error('SDK Iframe not ready'));
- return;
- }
- const requestId = `req_${++this.requestCounter}_${Date.now()}`;
- const message = createSdkMessage(type, payload, requestId);
- // Setup timeout
- const timeout = setTimeout(() => {
- this.pendingRequests.delete(requestId);
- reject(new Error(`Request timeout: ${type}`));
- }, this.config.timeout);
- // Store pending request
- this.pendingRequests.set(requestId, { resolve, reject, timeout });
- // Send message
- this.sdkIframe.contentWindow.postMessage(message, this.sdkOrigin);
- this.log('debug', `Sent: ${type}`, payload);
- });
- }
- log(level, message, data) {
- if (!this.config.debug && level === 'debug')
- return;
- const prefix = '[GameBridge]';
- switch (level) {
- case 'debug':
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
-}
-// =============================================================================
-// FACTORY
-// =============================================================================
-let bridgeInstance = null;
-/**
- * Get or create GameBridge instance
- */
-export function getGameBridge(config) {
- if (!bridgeInstance && config) {
- bridgeInstance = new GameBridge(config);
- }
- if (!bridgeInstance) {
- throw new Error('GameBridge not initialized. Call with config first.');
- }
- return bridgeInstance;
-}
-/**
- * Destroy GameBridge instance
- */
-export function destroyGameBridge() {
- bridgeInstance?.destroy();
- bridgeInstance = null;
-}
-//# sourceMappingURL=GameBridge.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js.map b/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js.map
deleted file mode 100644
index 2288912..0000000
--- a/G102-sequence/sdk/package/dist/esm/game-bridge/GameBridge.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameBridge.js","sourceRoot":"","sources":["../../../src/game-bridge/GameBridge.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/game-bridge/index.js b/G102-sequence/sdk/package/dist/esm/game-bridge/index.js
deleted file mode 100644
index 0984700..0000000
--- a/G102-sequence/sdk/package/dist/esm/game-bridge/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Game Bridge exports
- * Dành cho game developers tích hợp vào game
- */
-export { GameBridge, getGameBridge, destroyGameBridge, } from './GameBridge';
-// Re-export types từ sdk-iframe
-export { SDK_MESSAGE_TYPES, } from '../sdk-iframe/types';
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/game-bridge/index.js.map b/G102-sequence/sdk/package/dist/esm/game-bridge/index.js.map
deleted file mode 100644
index ec9700e..0000000
--- a/G102-sequence/sdk/package/dist/esm/game-bridge/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/game-bridge/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,UAAU,EACV,aAAa,EACb,iBAAiB,GAGpB,MAAM,cAAc,CAAC;AAEtB,gCAAgC;AAChC,OAAO,EACH,iBAAiB,GAYpB,MAAM,qBAAqB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/index.js b/G102-sequence/sdk/package/dist/esm/index.js
deleted file mode 100644
index ef2756a..0000000
--- a/G102-sequence/sdk/package/dist/esm/index.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Game Iframe SDK - Main Entry Point
- *
- * @packageDocumentation
- * @module game-iframe-sdk
- *
- * Architecture:
- * - types.ts: Type definitions
- * - mappers.ts: Data transformation/mapping
- * - EventEmitter.ts: Simple typed event emitter
- * - MessageHandler.ts: Handle incoming messages from iframe
- * - MessageSender.ts: Send messages to iframe
- * - GameIframeSDK.ts: Main SDK (composes above layers)
- * - useGameIframeSDK.ts: React hook
- *
- * @example Browser/Vanilla JS
- * ```typescript
- * import { GameIframeSDK } from 'game-iframe-sdk';
- *
- * const sdk = new GameIframeSDK({
- * iframeOrigin: 'http://senaai.vn:1357',
- * debug: true
- * });
- *
- * sdk.setIframe(document.getElementById('gameIframe'));
- *
- * sdk.on('gameReady', () => {
- * sdk.sendGameData({ game_id: 'xxx', user_id: 'yyy', questions: [...] });
- * });
- * ```
- *
- * @example React
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const { isReady, sendGameData } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onAnswerReport: (data) => submitToServer(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-// =============================================================================
-// CORE SDK
-// =============================================================================
-export { GameIframeSDK, createGameIframeSDK, getGameIframeSDK, destroyGameIframeSDK, } from './GameIframeSDK';
-// =============================================================================
-// LAYERS (for advanced usage)
-// =============================================================================
-export { MessageHandler } from './MessageHandler';
-export { MessageSender } from './MessageSender';
-export { EventEmitter } from './EventEmitter';
-// Mappers removed - mapped data should be handled by the application
-// =============================================================================
-// =============================================================================
-// REACT HOOK
-// =============================================================================
-export { useGameIframeSDK } from './useGameIframeSDK';
-// =============================================================================
-// TYPES
-// =============================================================================
-export {
-// Message Types
-MESSAGE_TYPES, DEFAULT_CONFIG, } from './types';
-// =============================================================================
-// KIT (Helper Mappers, API, Components)
-// =============================================================================
-import * as Kit from './kit';
-export { Kit };
-// =============================================================================
-// CLIENT SDK (for Game Iframe - used by game developers)
-// =============================================================================
-import * as Client from './client';
-export { Client };
-export { GameClientSDK, getGameClientSDK, destroyGameClientSDK, } from './client';
-// =============================================================================
-// SDK IFRAME (Hidden iframe - runs on separate domain for security)
-// =============================================================================
-import * as SdkIframe from './sdk-iframe';
-export { SdkIframe };
-export { SdkIframeCore, SDK_MESSAGE_TYPES, } from './sdk-iframe';
-// =============================================================================
-// GAME BRIDGE (For game developers - communicates with SDK Iframe)
-// =============================================================================
-import * as GameBridgeModule from './game-bridge';
-export { GameBridgeModule };
-export { GameBridge, getGameBridge, destroyGameBridge, } from './game-bridge';
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/index.js.map b/G102-sequence/sdk/package/dist/esm/index.js.map
deleted file mode 100644
index b02b21e..0000000
--- a/G102-sequence/sdk/package/dist/esm/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAEhF,OAAO,EACH,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,qEAAqE;AACrE,gFAAgF;AAEhF,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,OAAO;AACH,gBAAgB;AAChB,aAAa,EAiBb,cAAc,GAMjB,MAAM,SAAS,CAAC;AAEjB,gFAAgF;AAChF,wCAAwC;AACxC,gFAAgF;AAEhF,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,gFAAgF;AAChF,yDAAyD;AACzD,gFAAgF;AAEhF,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GAQvB,MAAM,UAAU,CAAC;AAElB,gFAAgF;AAChF,oEAAoE;AACpE,gFAAgF;AAEhF,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EACH,aAAa,EACb,iBAAiB,GAapB,MAAM,cAAc,CAAC;AAEtB,gFAAgF;AAChF,mEAAmE;AACnE,gFAAgF;AAEhF,OAAO,KAAK,gBAAgB,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,OAAO,EACH,UAAU,EACV,aAAa,EACb,iBAAiB,GAGpB,MAAM,eAAe,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js b/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js
deleted file mode 100644
index 4e48e14..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js
+++ /dev/null
@@ -1,444 +0,0 @@
-/**
- * GameDataHandler - Data Sanitizer & Scorer
- *
- * Game Codes:
- * - G001: Quiz text-text
- * - G002: Quiz audio-text (audio question, text answer)
- * - G003: Quiz text-audio (text question, audio answer)
- * - G004: Quiz image-text (image question, text answer)
- * - G005: Quiz text-image (text question, image answer)
- *
- * - G110: Sequence Word - no audio
- * - G111: Sequence Word - có audio, missing_letter_count từ item
- * - G112: Sequence Word - có audio, missing_letter_count từ item
- * - G113: Sequence Word - có audio, missing_letter_count từ item
- *
- * - G120: Sequence Sentence - no audio
- * - G121: Sequence Sentence - có audio, missing_letter_count từ item
- * - G122: Sequence Sentence - có audio, missing_letter_count từ item
- * - G123: Sequence Sentence - có audio, missing_letter_count từ item
- */
-// Game code metadata
-export const GAME_CODES = {
- // Quiz
- G001: { name: 'Quiz Text-Text', category: 'quiz', hasAudio: false, hasImage: false },
- G002: { name: 'Quiz Audio-Text', category: 'quiz', hasAudio: true, hasImage: false },
- G003: { name: 'Quiz Text-Audio', category: 'quiz', hasAudio: true, hasImage: false },
- G004: { name: 'Quiz Image-Text', category: 'quiz', hasAudio: false, hasImage: true },
- G005: { name: 'Quiz Text-Image', category: 'quiz', hasAudio: false, hasImage: true },
- // Sequence Word
- G110: { name: 'Sequence Word', category: 'sequence_word', hasAudio: false },
- G111: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- G112: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- G113: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- // Sequence Sentence
- G120: { name: 'Sequence Sentence', category: 'sequence_sentence', hasAudio: false },
- G121: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
- G122: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
- G123: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
-};
-export function getGameCategory(code) {
- return GAME_CODES[code]?.category || 'unknown';
-}
-// =============================================================================
-// SANITIZE DATA FOR CLIENT (REMOVE ANSWERS)
-// =============================================================================
-/**
- * Sanitize game data before sending to iframe
- * CRITICAL: Never send answers/correct data to client
- */
-export function sanitizeForClient(code, items) {
- if (!Array.isArray(items))
- return [];
- switch (code) {
- // ===== QUIZ VARIANTS =====
- case 'G001': // Quiz text-text
- return sanitizeQuizTextText(items);
- case 'G002': // Quiz audio-text
- return sanitizeQuizAudioText(items);
- case 'G003': // Quiz text-audio
- return sanitizeQuizTextAudio(items);
- case 'G004': // Quiz image-text
- return sanitizeQuizImageText(items);
- case 'G005': // Quiz text-image
- return sanitizeQuizTextImage(items);
- // ===== SEQUENCE WORD VARIANTS =====
- case 'G110': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G111': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G112': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G113': // Sequence word
- return sanitizeSequenceWord(items);
- // ===== SEQUENCE SENTENCE VARIANTS =====
- case 'G120': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G121': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G122': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G123': // Sequence sentence
- return sanitizeSequenceSentence(items);
- default:
- console.warn(`[GameDataHandler] Unknown game code: ${code}, returning raw data`);
- return items;
- }
-}
-// =============================================================================
-// QUIZ SANITIZERS
-// =============================================================================
-/**
- * G001: Quiz Text-Text
- * Client receives: id, question, options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextText(items) {
- return items.map(item => {
- // Normalize options to {text: string}
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- // Shuffle to hide answer position
- shuffleArray(options);
- // Save shuffled text order for SDK to resolve index
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledTexts, // SDK internal
- };
- });
-}
-/**
- * G002: Quiz Audio-Text
- * Client receives: id, question (audio URL), options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizAudioText(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- question: item.audio || item.audio_url,
- options: options,
- __shuffledOptions: shuffledTexts,
- };
- });
-}
-/**
- * G003: Quiz Text-Audio
- * Client receives: id, question (text), options (audio URLs shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextAudio(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { audio: o };
- }
- if (o && typeof o === 'object') {
- const audioUrl = o.audio || o.audio_url || '';
- return { audio: String(audioUrl) };
- }
- return { audio: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledAudios = options.map((o) => String(o.audio ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledAudios,
- };
- });
-}
-/**
- * G004: Quiz Image-Text
- * Client receives: id, image_url, question (hint), options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizImageText(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- image_url: item.image_url,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledTexts,
- };
- });
-}
-/**
- * G005: Quiz Text-Image
- * Client receives: id, question (text), options (image URLs shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextImage(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { image_url: o };
- }
- if (o && typeof o === 'object') {
- const imageUrl = o.image_url || o.image || '';
- return { image_url: String(imageUrl) };
- }
- return { image_url: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledUrls = options.map((o) => String(o.image_url ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options, // Each option has {image_url: ...}
- __shuffledOptions: shuffledUrls,
- };
- });
-}
-// =============================================================================
-// SEQUENCE WORD SANITIZERS
-// =============================================================================
-/**
- * Sequence Word (G110-G113)
- * Client receives: id, question (array with blanks), options (missing letters shuffled), audio_url (optional)
- * Client does NOT receive: word, parts, answer, missing_letter_count
- *
- * Logic:
- * 1. Read missing_letter_count from item (count of letters to blank out)
- * 2. Randomly select positions to blank
- * 3. question: array with blanks at selected positions
- * 4. options: extracted missing letters (shuffled)
- */
-function sanitizeSequenceWord(items) {
- return items.map(item => {
- const parts = item.answer || item.parts || [];
- const missingCount = item.missing_letter_count || 0;
- if (missingCount === 0 || parts.length === 0) {
- // No missing - all visible
- return {
- id: item.id,
- question: [...parts],
- options: [],
- ...(item.audio_url && { audio_url: item.audio_url })
- };
- }
- // Randomly select which positions to blank
- const allIndices = Array.from({ length: parts.length }, (_, i) => i);
- const blankIndices = new Set();
- const count = Math.min(missingCount, parts.length);
- while (blankIndices.size < count) {
- const randomIdx = Math.floor(Math.random() * allIndices.length);
- const actualIdx = allIndices[randomIdx];
- blankIndices.add(actualIdx);
- allIndices.splice(randomIdx, 1);
- }
- // Build question array with blanks at random positions
- const question = parts.map((p, i) => blankIndices.has(i) ? "" : String(p));
- // Extract missing letters and shuffle
- const missingLetters = Array.from(blankIndices).map(i => String(parts[i]));
- shuffleArray(missingLetters);
- const result = {
- id: item.id,
- question, // e.g. ["H", "", "L", "", "O"]
- options: missingLetters, // e.g. ["L", "E"] - shuffled
- __shuffledOptions: [...missingLetters] // SDK internal: to resolve indices
- };
- if (item.audio_url) {
- result.audio_url = item.audio_url;
- }
- // CRITICAL: Do NOT send word, parts, answer, missing_letter_count
- return result;
- });
-}
-// =============================================================================
-// SEQUENCE SENTENCE SANITIZERS
-// =============================================================================
-/**
- * Sequence Sentence (G120-G123)
- * Client receives: id, question (array with blanks), options (missing words shuffled), audio_url (optional)
- * Client does NOT receive: sentence, parts, answer, missing_letter_count
- *
- * Logic: Same as Sequence Word
- * 1. Read missing_letter_count from item
- * 2. Randomly select positions to blank
- * 3. question: array with blanks
- * 4. options: extracted missing words (shuffled)
- */
-function sanitizeSequenceSentence(items) {
- return items.map(item => {
- const parts = item.answer || item.parts || [];
- const missingCount = item.missing_letter_count || 0;
- if (missingCount === 0 || parts.length === 0) {
- // No missing - all visible
- return {
- id: item.id,
- question: [...parts],
- options: [],
- ...(item.audio_url && { audio_url: item.audio_url })
- };
- }
- // Randomly select which positions to blank
- const allIndices = Array.from({ length: parts.length }, (_, i) => i);
- const blankIndices = new Set();
- const count = Math.min(missingCount, parts.length);
- while (blankIndices.size < count) {
- const randomIdx = Math.floor(Math.random() * allIndices.length);
- const actualIdx = allIndices[randomIdx];
- blankIndices.add(actualIdx);
- allIndices.splice(randomIdx, 1);
- }
- // Build question array with blanks at random positions
- const question = parts.map((p, i) => blankIndices.has(i) ? "" : String(p));
- // Extract missing words and shuffle
- const missingWords = Array.from(blankIndices).map(i => String(parts[i]));
- shuffleArray(missingWords);
- const result = {
- id: item.id,
- question, // e.g. ["I", "", "reading", ""]
- options: missingWords, // e.g. ["love", "books"] - shuffled
- __shuffledOptions: [...missingWords] // SDK internal
- };
- if (item.audio_url) {
- result.audio_url = item.audio_url;
- }
- // CRITICAL: Do NOT send sentence, parts, answer, missing_letter_count
- return result;
- });
-}
-/**
- * Check if player's answer is correct
- *
- * @param code - Game code (G001, G110, etc.)
- * @param originalItem - Original item from server (has answer field!)
- * @param playerAnswer - Player's answer (text for quiz, array for sequence)
- */
-export function checkAnswer(code, originalItem, playerAnswer) {
- switch (code) {
- // ===== QUIZ VARIANTS (G001-G005) =====
- case 'G001': // Quiz Text-Text
- case 'G002': // Quiz Audio-Text
- case 'G003': // Quiz Text-Audio
- case 'G004': // Quiz Image-Text
- case 'G005': // Quiz Text-Image
- return checkQuizAnswer(originalItem, playerAnswer);
- // ===== SEQUENCE WORD VARIANTS (G110-G113) =====
- case 'G110': // Sequence Word
- case 'G111': // Sequence Word Audio
- case 'G112': // Sequence Word Audio
- case 'G113': // Sequence Word Audio
- return checkSequenceAnswer(originalItem, playerAnswer);
- // ===== SEQUENCE SENTENCE VARIANTS (G120-G123) =====
- case 'G120': // Sequence Sentence
- case 'G121': // Sequence Sentence Audio
- case 'G122': // Sequence Sentence Audio
- case 'G123': // Sequence Sentence Audio
- return checkSequenceAnswer(originalItem, playerAnswer);
- default:
- console.warn(`[GameDataHandler] Unknown game code for scoring: ${code}`);
- return { isCorrect: false, score: 0 };
- }
-}
-// Quiz Scoring
-function checkQuizAnswer(item, answerChoice) {
- const correctAnswer = String(item.answer || '');
- if (!correctAnswer) {
- return { isCorrect: false, score: 0, feedback: 'No correct answer defined' };
- }
- let playerAnswerText;
- if (typeof answerChoice === 'number') {
- // Index: resolve from original options
- if (Array.isArray(item.options)) {
- const v = item.options[answerChoice];
- if (typeof v === 'string') {
- playerAnswerText = v;
- }
- else if (v && typeof v === 'object' && 'text' in v) {
- playerAnswerText = String(v.text ?? '');
- }
- else {
- playerAnswerText = String(v ?? '');
- }
- }
- else {
- return { isCorrect: false, score: 0, feedback: 'Invalid question options' };
- }
- }
- else {
- // Direct text answer
- if (answerChoice && typeof answerChoice === 'object' && 'text' in answerChoice) {
- playerAnswerText = String(answerChoice.text ?? '');
- }
- else {
- playerAnswerText = String(answerChoice ?? '');
- }
- }
- const isCorrect = playerAnswerText.toLowerCase().trim() === correctAnswer.toLowerCase().trim();
- return {
- isCorrect,
- score: isCorrect ? 1 : 0,
- feedback: isCorrect
- ? `✅ Correct! "${playerAnswerText}" matches answer "${correctAnswer}"`
- : `❌ Wrong. You chose "${playerAnswerText}" but correct answer is "${correctAnswer}"`
- };
-}
-// Sequence Scoring
-function checkSequenceAnswer(item, answer) {
- const correctOrder = item.answer || item.parts;
- if (!Array.isArray(answer) || !Array.isArray(correctOrder)) {
- return { isCorrect: false, score: 0 };
- }
- const isCorrect = arraysEqual(answer, correctOrder);
- return {
- isCorrect,
- score: isCorrect ? 1 : 0,
- };
-}
-// =============================================================================
-// UTILITIES
-// =============================================================================
-function shuffleArray(array) {
- for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- [array[i], array[j]] = [array[j], array[i]];
- }
-}
-function arraysEqual(a, b) {
- if (a.length !== b.length)
- return false;
- return a.every((val, idx) => {
- if (typeof val === 'string' && typeof b[idx] === 'string') {
- return val.toLowerCase().trim() === b[idx].toLowerCase().trim();
- }
- return val === b[idx];
- });
-}
-//# sourceMappingURL=GameDataHandler.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js.map b/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js.map
deleted file mode 100644
index 774fafc..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/GameDataHandler.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameDataHandler.js","sourceRoot":"","sources":["../../../src/kit/GameDataHandler.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/api.js b/G102-sequence/sdk/package/dist/esm/kit/api.js
deleted file mode 100644
index ab836bf..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/api.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Game API Client Kit
- * Standardized API client for communicating with Game Backend
- */
-export class GameApiClient {
- constructor(config) {
- this.config = config;
- }
- async request(method, endpoint, body) {
- const url = `${this.config.baseUrl}${endpoint}`;
- const headers = {
- 'Content-Type': 'application/json',
- ...(this.config.getHeaders ? this.config.getHeaders() : {})
- };
- try {
- const res = await fetch(url, {
- method,
- headers,
- body: body ? JSON.stringify(body) : undefined
- });
- if (!res.ok) {
- const errorBody = await res.text();
- let errorMessage = `API Error ${res.status}: ${res.statusText}`;
- let errorCode;
- try {
- const jsonError = JSON.parse(errorBody);
- // Capture error code from response
- if (jsonError.code !== undefined) {
- errorCode = jsonError.code;
- }
- if (jsonError.message)
- errorMessage += ` - ${jsonError.message}`;
- else if (jsonError.error)
- errorMessage += ` - ${jsonError.error}`;
- }
- catch (e) {
- if (errorBody && errorBody.length < 200)
- errorMessage += ` - ${errorBody}`;
- }
- // Throw error object with code and message
- const error = new Error(errorMessage);
- error.code = errorCode;
- error.httpStatus = res.status;
- throw error;
- }
- return await res.json();
- }
- catch (error) {
- console.error('[GameApiClient] Request failed:', error);
- throw error;
- }
- }
- async getGameWithProgress(assignmentId, studentId, refresh = false) {
- return this.request('GET', `/submissions/live/init/${assignmentId}/${studentId}${refresh ? '?refresh=1' : ''}`);
- }
- async startLiveSession(assignmentId, studentId, refresh = false) {
- return this.request('POST', `/submissions/live/start${refresh ? '?refresh=1' : ''}`, {
- assignment_id: assignmentId,
- student_id: studentId
- });
- }
- async submitAnswer(assignmentId, studentId, questionId, answer, timeSpent = 5, isTimeout = false) {
- return this.request('POST', '/submissions/live/answer', {
- assignment_id: assignmentId,
- student_id: studentId,
- question_id: questionId,
- selected_answer: answer,
- time_spent: timeSpent,
- is_timeout: isTimeout
- });
- }
- async completeSession(assignmentId, studentId) {
- return this.request('POST', '/submissions/live/complete', {
- assignment_id: assignmentId,
- student_id: studentId
- });
- }
- async getLeaderboard(assignmentId, studentId) {
- return this.request('GET', `/submissions/leaderboard/${assignmentId}?student_id=${studentId}`);
- }
-}
-//# sourceMappingURL=api.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/api.js.map b/G102-sequence/sdk/package/dist/esm/kit/api.js.map
deleted file mode 100644
index 4e47be7..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/api.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/kit/api.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/index.js b/G102-sequence/sdk/package/dist/esm/kit/index.js
deleted file mode 100644
index e99d834..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './mappers';
-export * from './api';
-export * from './GameDataHandler';
-export * from './react/GamePlayer';
-export * from './react/GameTestPlayer';
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/index.js.map b/G102-sequence/sdk/package/dist/esm/kit/index.js.map
deleted file mode 100644
index 4cd1438..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kit/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/mappers.js b/G102-sequence/sdk/package/dist/esm/kit/mappers.js
deleted file mode 100644
index 0866200..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/mappers.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Mappers Kit
- * Helper functions to transform data between Client App and Game Iframe
- */
-export function prepareCompletedQuestions(answeredQuestions) {
- return (answeredQuestions || []).map(a => ({
- id: a.id || a.questionId,
- result: (a.isCorrect || a.result === 1) ? 1 : 0,
- }));
-}
-export function createGamePayload(options) {
- const { gameId, userId, gameData, answeredQuestions = [], endTimeIso } = options;
- const completed_question_ids = prepareCompletedQuestions(answeredQuestions);
- // Ưu tiên lấy field .questions hoặc .data, hoặc dùng chính gameData nếu nó là mảng
- let data = [];
- if (Array.isArray(gameData)) {
- data = gameData;
- }
- else if (gameData && Array.isArray(gameData.questions)) {
- data = gameData.questions;
- }
- else if (gameData && Array.isArray(gameData.data)) {
- data = gameData.data;
- }
- const payload = {
- game_id: gameId,
- user_id: userId,
- data: data,
- completed_question_ids: completed_question_ids,
- // Merge các field metadata khác
- ...(typeof gameData === 'object' && !Array.isArray(gameData) ? gameData : {}),
- // Merge extraData
- ...(options.extraData || {})
- };
- // Inject end_time_iso (absolute timestamp for accurate sync)
- if (endTimeIso) {
- payload.end_time_iso = endTimeIso;
- }
- return payload;
-}
-export function createLeaderboardPayload(apiData) {
- const topPlayers = apiData.topPlayers || [];
- const userRank = apiData.userRank || null;
- return {
- top_players: topPlayers.map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.user_id,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: userRank ? {
- rank: userRank.rank,
- name: userRank.name || userRank.studentName,
- score: userRank.score ?? userRank.finalScore ?? 0,
- student_id: userRank.studentId || userRank.userId,
- time_spent: userRank.timeSpent ?? userRank.time_spent ?? 0,
- completed_at: userRank.completedAt
- } : null,
- };
-}
-export function normalizeAnswerReport(data) {
- // Simplified per user request
- // Input: { question_id: "Q1", result: 1, choice: "2" }
- return {
- question_id: data.question_id || data.questionId || data.id,
- choice: data.choice ?? data.selected_answer ?? data.selectedAnswer,
- result: data.result ?? (data.is_correct ? 1 : 0),
- is_correct: !!(data.result === 1 || data.is_correct === true),
- time_spent: data.time_spent ?? 5,
- is_timeout: !!data.is_timeout
- };
-}
-//# sourceMappingURL=mappers.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/mappers.js.map b/G102-sequence/sdk/package/dist/esm/kit/mappers.js.map
deleted file mode 100644
index ac35c28..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/mappers.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../../src/kit/mappers.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js b/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js
deleted file mode 100644
index 88c5bf6..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js
+++ /dev/null
@@ -1,579 +0,0 @@
-import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
-import { useEffect, useState, useRef, useCallback } from 'react';
-import { useGameIframeSDK } from '../../useGameIframeSDK';
-import { GameApiClient } from '../api';
-import { createGamePayload, normalizeAnswerReport } from '../mappers';
-// Session Error Codes (synced with backend)
-export const SessionErrorCodes = {
- SESSION_NOT_STARTED: -60,
- SESSION_ENDED: -61,
- SESSION_COMPLETED: -62,
- SESSION_TIMEOUT: -63,
- SESSION_NOT_FOUND: -64,
- SESSION_ALREADY_ANSWERED: -65,
-};
-export const GamePlayer = ({ apiConfig, assignmentId, studentId, className, style, debug = false, onComplete, onError, onGameLoaded, extraGameData, onLog, onSessionStatus, renderLoading, renderError, loadingTimeout = 30000 }) => {
- const iframeRef = useRef(null);
- const [gameUrl, setGameUrl] = useState('');
- const [gameState, setGameState] = useState(null);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
- const [hasLoadedGame, setHasLoadedGame] = useState(false);
- const [apiClient] = useState(() => new GameApiClient(apiConfig));
- // Refs to prevent infinite loops
- const sendLeaderboardRef = useRef(null);
- const hasInitRef = useRef(false); // Track if init has been called
- const callbacksRef = useRef({ onGameLoaded, onLog, onSessionStatus, onError }); // Stable callback refs
- // Update callback refs on each render
- callbacksRef.current = { onGameLoaded, onLog, onSessionStatus, onError };
- // Helper: Create structured error
- const createError = useCallback((err) => {
- const errorMsg = err?.message || err?.error || String(err);
- const errorCode = err?.code; // Error code from API response
- // Check error code first (more reliable than message parsing)
- if (errorCode !== undefined) {
- // Session not started
- if (errorCode === SessionErrorCodes.SESSION_NOT_STARTED) {
- return {
- type: 'not_started',
- code: errorCode,
- message: errorMsg || 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- // Session ended
- if (errorCode === SessionErrorCodes.SESSION_ENDED) {
- return {
- type: 'session',
- code: errorCode,
- message: errorMsg || 'Bài tập đã kết thúc',
- details: err,
- canRetry: false
- };
- }
- // Session completed
- if (errorCode === SessionErrorCodes.SESSION_COMPLETED) {
- return {
- type: 'session',
- code: errorCode,
- message: errorMsg || 'Bạn đã hoàn thành bài tập này rồi',
- details: err,
- canRetry: false
- };
- }
- // Session timeout
- if (errorCode === SessionErrorCodes.SESSION_TIMEOUT) {
- return {
- type: 'timeout',
- code: errorCode,
- message: errorMsg || 'Đã hết thời gian làm bài',
- details: err,
- canRetry: false
- };
- }
- }
- // Fallback: Parse error message
- // API errors
- if (errorMsg.includes('API Error') || errorMsg.includes('Failed to fetch')) {
- // Check if it contains session-related message
- if (errorMsg.includes('chưa bắt đầu')) {
- return {
- type: 'not_started',
- message: 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- return {
- type: 'api',
- message: errorMsg,
- details: err,
- canRetry: true
- };
- }
- // Network errors
- if (errorMsg.includes('network') || errorMsg.includes('ECONNREFUSED')) {
- return {
- type: 'network',
- message: 'Lỗi kết nối mạng. Vui lòng kiểm tra internet.',
- details: err,
- canRetry: true
- };
- }
- // Session errors (message-based fallback)
- if (errorMsg.includes('chưa bắt đầu')) {
- return {
- type: 'not_started',
- message: errorMsg || 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- if (errorMsg.includes('hết thời gian') || errorMsg.includes('đã kết thúc') ||
- errorMsg.includes('đã hoàn thành') || errorMsg.includes('session')) {
- return {
- type: 'session',
- message: errorMsg,
- details: err,
- canRetry: false
- };
- }
- // Timeout errors
- if (errorMsg.includes('timeout') || errorMsg.includes('timed out')) {
- return {
- type: 'timeout',
- message: 'Kết nối quá lâu. Vui lòng thử lại.',
- details: err,
- canRetry: true
- };
- }
- return {
- type: 'unknown',
- message: errorMsg || 'Đã xảy ra lỗi không xác định',
- details: err,
- canRetry: true
- };
- }, []);
- // Helper: Handle error with callback
- const handleError = useCallback((err) => {
- const gameError = createError(err);
- setError(gameError);
- setLoading(false);
- if (onError) {
- onError(gameError);
- }
- if (onLog) {
- onLog(`[SDK ERR] ${gameError.type}: ${gameError.message}`, 'error');
- }
- }, [createError, onError, onLog]);
- // Retry function
- const retryInit = useCallback(() => {
- if (callbacksRef.current.onLog)
- callbacksRef.current.onLog('[SDK] Retrying initialization...', 'info');
- hasInitRef.current = false; // Allow re-init
- setError(null);
- setLoading(true);
- setGameUrl('');
- setGameState(null);
- }, []);
- // Define Handlers
- const handleAnswer = useCallback(async (data) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Answer Raw: ${JSON.stringify(data)}`, 'info');
- const report = normalizeAnswerReport(data);
- if (onLog)
- onLog(`[SDK] Processed Answer: ID ${report.question_id} | Choice: ${report.choice} | ${report.is_correct ? 'Correct' : 'Wrong'}`, 'info');
- if (onLog)
- onLog(`[API REQ] Submitting Answer ID ${report.question_id}...`, 'info');
- const res = await apiClient.submitAnswer(assignmentId, studentId, report.question_id, report.choice, report.time_spent, report.is_timeout);
- if (onLog)
- onLog(`[API RES] Submit Result: ${JSON.stringify(res)}`, 'success');
- }
- catch (err) {
- console.error('[GamePlayer] Submit error:', err);
- if (onLog)
- onLog(`[API ERR] Submit Failed: ${err.message}`, 'error');
- }
- }, [apiClient, assignmentId, studentId, onLog]);
- const handleFinalResult = useCallback(async (data) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Final Result Raw: ${JSON.stringify(data)}`, 'info');
- if (onLog)
- onLog('[SDK] Game Complete. Calling API...', 'info');
- const res = await apiClient.completeSession(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Session Completed. Score: ${res.data?.finalScore}`, 'success');
- // Auto-refresh leaderboard after completion to ensure user rank is included
- if (onLog)
- onLog('[SDK] Auto-refreshing leaderboard after completion...', 'info');
- await new Promise(resolve => setTimeout(resolve, 500)); // Small delay for backend to process
- try {
- const lbRes = await apiClient.getLeaderboard(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Post-completion Leaderboard: ${JSON.stringify(lbRes)}`, 'success');
- if (lbRes.success && lbRes.data && sendLeaderboardRef.current) {
- const leaderboardData = {
- top_players: (lbRes.data.topPlayers || []).map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.userId,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: lbRes.data.userRank ? {
- rank: lbRes.data.userRank.rank,
- name: lbRes.data.userRank.name || lbRes.data.userRank.studentName,
- score: lbRes.data.userRank.score ?? lbRes.data.userRank.finalScore ?? 0,
- student_id: lbRes.data.userRank.studentId || lbRes.data.userRank.userId,
- time_spent: lbRes.data.userRank.timeSpent ?? lbRes.data.userRank.time_spent ?? 0,
- completed_at: lbRes.data.userRank.completedAt
- } : null
- };
- if (onLog)
- onLog(`[SDK SEND] Updated Leaderboard: ${JSON.stringify(leaderboardData)}`, 'info');
- sendLeaderboardRef.current(leaderboardData);
- }
- }
- catch (lbErr) {
- if (onLog)
- onLog(`[API ERR] Leaderboard refresh failed: ${lbErr.message}`, 'warning');
- }
- if (onComplete)
- onComplete(res);
- }
- catch (err) {
- console.error('[GamePlayer] Complete error:', err);
- if (onLog)
- onLog(`[API ERR] Complete Failed: ${err.message}`, 'error');
- if (onError)
- onError(err);
- }
- }, [apiClient, assignmentId, studentId, onComplete, onError, onLog]);
- // SDK Hook
- const { isReady, sendGameData, sendLeaderboard } = useGameIframeSDK({
- iframeRef,
- iframeOrigin: '*',
- debug,
- onGameReady: () => {
- if (onLog)
- onLog('[SDK RECV] Iframe Ready', 'success');
- },
- onAnswerReport: handleAnswer,
- onFinalResult: handleFinalResult,
- onLeaderboardRequest: async (top) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Leaderboard Request Raw: top=${top}`, 'info');
- if (onLog)
- onLog(`[API REQ] Fetching Leaderboard (top ${top})...`, 'info');
- const res = await apiClient.getLeaderboard(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Leaderboard Raw: ${JSON.stringify(res)}`, 'success');
- if (res.success && res.data) {
- const leaderboardData = {
- top_players: (res.data.topPlayers || []).map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.userId,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: res.data.userRank ? {
- rank: res.data.userRank.rank,
- name: res.data.userRank.name || res.data.userRank.studentName,
- score: res.data.userRank.score ?? res.data.userRank.finalScore ?? 0,
- student_id: res.data.userRank.studentId || res.data.userRank.userId,
- time_spent: res.data.userRank.timeSpent ?? res.data.userRank.time_spent ?? 0,
- completed_at: res.data.userRank.completedAt
- } : null
- };
- if (onLog)
- onLog(`[SDK SEND] Leaderboard Payload: ${JSON.stringify(leaderboardData)}`, 'info');
- const sent = sendLeaderboard(leaderboardData);
- if (onLog)
- onLog(sent ? '[SDK] Leaderboard sent successfully' : '[SDK ERR] Failed to send leaderboard', sent ? 'success' : 'error');
- }
- }
- catch (err) {
- console.error('[GamePlayer] Leaderboard error:', err);
- if (onLog)
- onLog(`[API ERR] Leaderboard Failed: ${err.message}`, 'error');
- }
- }
- });
- // Update ref after hook
- sendLeaderboardRef.current = sendLeaderboard;
- // 1. Fetch Game Data & Start Session
- useEffect(() => {
- let mounted = true;
- let loadingTimeoutId;
- const initGame = async () => {
- try {
- setLoading(true);
- setError(null);
- if (onLog)
- onLog('[SDK] Initializing Game...', 'info');
- // Set loading timeout
- loadingTimeoutId = setTimeout(() => {
- if (mounted && loading) {
- if (onLog)
- onLog('[SDK WARN] Loading taking longer than expected...', 'warning');
- }
- }, loadingTimeout);
- // getGameWithProgress đã tự động tạo/restore session trong backend
- // thông qua getOrCreateSubmissionCache - không cần gọi startLiveSession riêng
- const res = await apiClient.getGameWithProgress(assignmentId, studentId);
- if (!res.success || !res.data) {
- throw new Error(res.message || 'Failed to load game');
- }
- if (mounted) {
- // Check session status TRƯỚC để quyết định có load game hay không
- const session = res.data.session;
- const progress = res.data.progress;
- // Case 1: Already completed
- if (res.data.isFinished || session?.completed) {
- // CHỈ set error nếu CHƯA load game (lần đầu vào)
- if (!hasLoadedGame) {
- const errorObj = {
- type: 'session',
- message: 'Bạn đã hoàn thành bài tập này rồi',
- details: { score: progress?.score, answered: progress?.answered, total: progress?.total },
- canRetry: false
- };
- setError(errorObj);
- setLoading(false);
- clearTimeout(loadingTimeoutId);
- if (onError)
- onError(errorObj);
- if (onLog)
- onLog(`[SDK] ${errorObj.message}`, 'warning');
- }
- // Luôn gọi callback (cho cả 2 trường hợp)
- if (onSessionStatus) {
- onSessionStatus({
- type: 'completed',
- message: 'Bạn đã hoàn thành bài tập này',
- data: {
- answered: progress?.answered || 0,
- total: progress?.total || 0,
- score: progress?.score || 0
- }
- });
- }
- // Nếu CHƯA load game → STOP
- // Nếu ĐÃ load game → tiếp tục (cho game hiển thị leaderboard)
- if (!hasLoadedGame) {
- return; // ❌ STOP - không load game
- }
- }
- // Case 2: Session timeout
- if (session && session.remainingTime !== null && session.remainingTime <= 0) {
- // CHỈ set error nếu CHƯA load game
- if (!hasLoadedGame) {
- const errorObj = {
- type: 'timeout',
- message: 'Thời gian làm bài đã hết',
- details: { answered: progress?.answered, total: progress?.total },
- canRetry: false
- };
- setError(errorObj);
- setLoading(false);
- clearTimeout(loadingTimeoutId);
- if (onError)
- onError(errorObj);
- if (onLog)
- onLog(`[SDK] ${errorObj.message}`, 'warning');
- }
- // Luôn gọi callback
- if (onSessionStatus) {
- onSessionStatus({
- type: 'timeout',
- message: 'Thời gian làm bài đã hết',
- data: {
- answered: progress?.answered || 0,
- total: progress?.total || 0,
- score: progress?.score || 0,
- remainingTime: 0
- }
- });
- }
- // Nếu CHƯA load game → STOP
- if (!hasLoadedGame) {
- return; // ❌ STOP - không load game
- }
- }
- // Case 3: Valid session - LOAD game
- setGameState(res.data);
- setGameUrl(res.data.gameUrl);
- setLoading(false);
- setHasLoadedGame(true); // ✅ Đánh dấu đã load game
- clearTimeout(loadingTimeoutId);
- if (onGameLoaded)
- onGameLoaded(res.data);
- if (onLog)
- onLog(`[API RES] Game Loaded: ${res.data.title || res.data.gameType || assignmentId}`, 'success');
- // Notify session status for valid sessions
- if (session && onSessionStatus) {
- // Resumed session (có câu đã trả lời)
- if (progress && progress.answered > 0) {
- onSessionStatus({
- type: 'resumed',
- message: `Tiếp tục làm bài (Đã làm ${progress.answered}/${progress.total} câu)`,
- data: {
- answered: progress.answered,
- total: progress.total,
- score: progress.score,
- remainingTime: session.remainingTime,
- startedAt: session.startedAt
- }
- });
- }
- // New session
- else {
- onSessionStatus({
- type: 'new',
- message: 'Bắt đầu làm bài mới',
- data: {
- answered: 0,
- total: progress?.total || 0,
- score: 0,
- remainingTime: session.remainingTime,
- startedAt: session.startedAt
- }
- });
- }
- }
- // Log session info
- if (session && onLog) {
- const sessionInfo = `Session started at ${session.startedAt}, remaining: ${session.remainingTime}s`;
- onLog(`[SDK] ${sessionInfo}`, 'info');
- }
- }
- }
- catch (err) {
- console.error('[GamePlayer] Init error:', err);
- if (mounted) {
- handleError(err);
- }
- }
- };
- if (assignmentId && studentId && !hasInitRef.current) {
- hasInitRef.current = true; // Prevent re-init
- initGame();
- }
- return () => {
- mounted = false;
- hasInitRef.current = false; // ✅ Reset for StrictMode remount
- if (loadingTimeoutId)
- clearTimeout(loadingTimeoutId);
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [assignmentId, studentId]); // ✅ Chỉ re-init khi assignmentId hoặc studentId thay đổi
- // 2. Auto Send Data when Ready
- useEffect(() => {
- if (isReady && gameState) {
- // Get expiresAt from session (absolute timestamp for accurate sync)
- const getEndTimeIso = () => {
- const session = gameState.session;
- if (!session)
- return undefined;
- // Ưu tiên dùng expiresAt
- if (session.expiresAt) {
- return session.expiresAt;
- }
- // Fallback: tính từ startedAt + duration
- if (session.startedAt && session.duration) {
- const startTimeMs = new Date(session.startedAt).getTime();
- const expiresAtMs = startTimeMs + (session.duration * 1000);
- return new Date(expiresAtMs).toISOString();
- }
- return undefined;
- };
- const payload = createGamePayload({
- gameId: gameState.id,
- userId: studentId,
- gameData: gameState.jsonData,
- answeredQuestions: gameState.completed_question_ids,
- extraData: extraGameData,
- endTimeIso: getEndTimeIso() // ✅ Absolute timestamp
- });
- if (onLog)
- onLog(`[SDK SEND] Game Payload: ${JSON.stringify(payload)}`, 'info');
- sendGameData(payload);
- }
- }, [isReady, gameState, studentId, sendGameData, extraGameData, onLog]);
- // ===== RENDER =====
- // 1. Error State
- if (error) {
- if (renderError) {
- return _jsx(_Fragment, { children: renderError(error, retryInit) });
- }
- // Default error UI
- return (_jsxs("div", { className: "game-player-error", style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- height: '100%',
- padding: '2rem',
- textAlign: 'center',
- backgroundColor: '#f8f9fa',
- ...style
- }, children: [_jsx("div", { style: {
- fontSize: '3rem',
- marginBottom: '1rem'
- }, children: error.type === 'network' ? '🌐' :
- error.type === 'timeout' ? '⏱️' :
- error.type === 'session' ? '🔒' :
- error.type === 'not_started' ? '📅' : '⚠️' }), _jsx("h2", { style: {
- fontSize: '1.5rem',
- fontWeight: 'bold',
- marginBottom: '0.5rem',
- color: error.type === 'not_started' ? '#fd7e14' : '#dc3545'
- }, children: error.type === 'network' ? 'Lỗi Kết Nối' :
- error.type === 'timeout' ? 'Hết Giờ Làm Bài' :
- error.type === 'session' ? 'Phiên Làm Bài Đã Kết Thúc' :
- error.type === 'not_started' ? 'Bài Tập Chưa Bắt Đầu' :
- 'Đã Xảy Ra Lỗi' }), _jsx("p", { style: {
- fontSize: '1rem',
- color: '#6c757d',
- marginBottom: '1.5rem',
- maxWidth: '500px'
- }, children: error.message }), error.canRetry && (_jsx("button", { onClick: retryInit, style: {
- padding: '0.75rem 2rem',
- fontSize: '1rem',
- fontWeight: 'bold',
- color: '#fff',
- backgroundColor: '#007bff',
- border: 'none',
- borderRadius: '0.5rem',
- cursor: 'pointer',
- transition: 'background-color 0.2s'
- }, onMouseEnter: (e) => e.currentTarget.style.backgroundColor = '#0056b3', onMouseLeave: (e) => e.currentTarget.style.backgroundColor = '#007bff', children: "\uD83D\uDD04 Th\u1EED L\u1EA1i" })), !error.canRetry && (_jsx("p", { style: {
- fontSize: '0.875rem',
- color: '#6c757d',
- marginTop: '1rem'
- }, children: "Vui l\u00F2ng li\u00EAn h\u1EC7 gi\u00E1o vi\u00EAn ho\u1EB7c quay l\u1EA1i trang ch\u1EE7" }))] }));
- }
- // 2. Loading State
- if (loading || !gameUrl) {
- if (renderLoading) {
- return _jsx(_Fragment, { children: renderLoading() });
- }
- // Default loading UI
- return (_jsxs("div", { className: "game-player-loading", style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- height: '100%',
- backgroundColor: '#f8f9fa',
- ...style
- }, children: [_jsx("div", { style: {
- width: '50px',
- height: '50px',
- border: '5px solid #e9ecef',
- borderTop: '5px solid #007bff',
- borderRadius: '50%',
- animation: 'spin 1s linear infinite',
- marginBottom: '1rem'
- } }), _jsx("p", { style: {
- fontSize: '1.125rem',
- color: '#6c757d',
- fontWeight: '500'
- }, children: "\u0110ang t\u1EA3i tr\u00F2 ch\u01A1i..." }), _jsx("style", { children: `
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- ` })] }));
- }
- // 3. Game Iframe
- return (_jsx("iframe", { ref: iframeRef, src: gameUrl, className: className, style: { width: '100%', height: '100%', border: 'none', ...style }, allowFullScreen: true }));
-};
-//# sourceMappingURL=GamePlayer.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js.map b/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js.map
deleted file mode 100644
index f0242d4..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/react/GamePlayer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GamePlayer.js","sourceRoot":"","sources":["../../../../src/kit/react/GamePlayer.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js b/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js
deleted file mode 100644
index 6253804..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js
+++ /dev/null
@@ -1,112 +0,0 @@
-import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
-import { useRef, useEffect, useState } from 'react';
-import { useGameIframeSDK } from '../../useGameIframeSDK';
-/**
- * GameTestPlayer - Component test đơn giản
- *
- * Chỉ load game data vào iframe, KHÔNG gọi API
- * Dùng để test game iframe locally
- *
- * @example
- * ```tsx
- * console.log(`[${type}] ${msg}`)}
- * onAnswer={(data) => console.log('Answer:', data)}
- * onComplete={(result) => console.log('Complete:', result)}
- * />
- * ```
- */
-export const GameTestPlayer = ({ gameUrl, gameData, userId = 'test_user', gameId = 'test_game', extraData, endTimeIso, className, style, debug = false, onAnswer, onComplete, onLog, onLeaderboardRequest, mockLeaderboard }) => {
- const iframeRef = useRef(null);
- const [isLoading, setIsLoading] = useState(true);
- // SDK Hook
- const { isReady, sendGameData, sendLeaderboard } = useGameIframeSDK({
- iframeRef,
- iframeOrigin: '*',
- debug,
- onGameReady: () => {
- if (onLog)
- onLog('[TEST] Iframe Ready', 'success');
- setIsLoading(false);
- },
- onAnswerReport: (data) => {
- if (onLog)
- onLog(`[TEST] Answer: ${JSON.stringify(data)}`, 'info');
- if (onAnswer)
- onAnswer(data);
- },
- onFinalResult: (result) => {
- if (onLog)
- onLog(`[TEST] Complete: ${JSON.stringify(result)}`, 'success');
- if (onComplete)
- onComplete(result);
- },
- onLeaderboardRequest: (top) => {
- if (onLog)
- onLog(`[TEST] Leaderboard Request: top=${top}`, 'info');
- if (onLeaderboardRequest)
- onLeaderboardRequest(top);
- // Auto send mock leaderboard if provided
- if (mockLeaderboard) {
- if (onLog)
- onLog(`[TEST] Sending mock leaderboard`, 'info');
- sendLeaderboard(mockLeaderboard);
- }
- }
- });
- // Auto send game data when ready
- useEffect(() => {
- if (isReady && gameData) {
- const payload = {
- game_id: String(gameId),
- user_id: userId,
- data: gameData,
- completed_question_ids: [],
- ...(extraData || {})
- };
- if (endTimeIso) {
- payload.end_time_iso = endTimeIso;
- }
- if (onLog)
- onLog(`[TEST] Sending Game Data: ${gameData.length} items`, 'info');
- sendGameData(payload);
- }
- }, [isReady, gameData, gameId, userId, extraData, endTimeIso, sendGameData, onLog]);
- return (_jsxs("div", { style: { position: 'relative', width: '100%', height: '100%', ...style }, children: [isLoading && (_jsx("div", { style: {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- backgroundColor: 'rgba(255,255,255,0.9)',
- zIndex: 10
- }, children: _jsxs("div", { style: { textAlign: 'center' }, children: [_jsx("div", { style: {
- width: '40px',
- height: '40px',
- border: '4px solid #e9ecef',
- borderTop: '4px solid #007bff',
- borderRadius: '50%',
- animation: 'spin 1s linear infinite',
- margin: '0 auto 1rem'
- } }), _jsx("p", { style: { color: '#6c757d' }, children: "Loading game..." }), _jsx("style", { children: `
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- ` })] }) })), _jsx("iframe", { ref: iframeRef, src: gameUrl, className: className, style: {
- width: '100%',
- height: '100%',
- border: 'none'
- }, allowFullScreen: true })] }));
-};
-export default GameTestPlayer;
-//# sourceMappingURL=GameTestPlayer.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js.map b/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js.map
deleted file mode 100644
index ec0e910..0000000
--- a/G102-sequence/sdk/package/dist/esm/kit/react/GameTestPlayer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameTestPlayer.js","sourceRoot":"","sources":["../../../../src/kit/react/GameTestPlayer.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js b/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js
deleted file mode 100644
index 3868989..0000000
--- a/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js
+++ /dev/null
@@ -1,357 +0,0 @@
-/**
- * SenaGame SDK Loader
- *
- * Ready-to-use interface for game developers.
- * Handles SDK iframe creation, communication, and lifecycle.
- *
- * Usage:
- * ```html
- *
- *
- * ```
- *
- * @version 1.0.0
- */
-// ========================================
-// MESSAGE TYPES (matching SDK)
-// ========================================
-const MSG = {
- // Outgoing (Game → SDK)
- INIT: 'SDK_INIT',
- PUSH_DATA: 'SDK_PUSH_DATA',
- SUBMIT_ANSWER: 'SDK_CHECK_ANSWER',
- COMPLETE_GAME: 'SDK_COMPLETE_GAME',
- GET_STATUS: 'SDK_GET_STATUS',
- // Incoming (SDK → Game)
- READY: 'SDK_READY',
- DATA_READY: 'SDK_DATA_READY',
- ANSWER_RESULT: 'SDK_ANSWER_RESULT',
- GAME_COMPLETE: 'SDK_GAME_COMPLETE',
- SESSION_STARTED: 'SDK_SESSION_STARTED',
- STATUS: 'SDK_STATUS',
- ERROR: 'SDK_ERROR',
-};
-// ========================================
-// DEFAULT CONFIG
-// ========================================
-const DEFAULT_CONFIG = {
- iframePath: '../sdk-iframe/index.html',
- mode: 'preview',
- gameCode: '',
- debug: false,
- timeout: 10000,
- iframeStyle: 'position:fixed;width:1px;height:1px;left:-9999px;border:none;',
-};
-// ========================================
-// SENA GAME SDK CLASS
-// ========================================
-export class SenaGameSDK {
- constructor(config) {
- this.iframe = null;
- this.isReady = false;
- this.isDataReady = false;
- this.pendingMessages = [];
- this.initResolver = null;
- this.timeoutId = null;
- this.config = { ...DEFAULT_CONFIG, ...config };
- // --- CLEANUP OLD LISTENERS ---
- // Tránh trường hợp init SDK nhiều lần bị trùng listener cũ
- const oldSDK = window._sena_game_sdk_instance;
- if (oldSDK && typeof oldSDK.destroy === 'function') {
- oldSDK.destroy();
- }
- window._sena_game_sdk_instance = this;
- // Create promise for ready state
- this.initPromise = new Promise((resolve, reject) => {
- this.initResolver = { resolve, reject };
- });
- // Bind methods
- this._handleMessage = this._handleMessage.bind(this);
- // Auto-initialize
- this._init();
- }
- // ----------------------------------------
- // PUBLIC API
- // ----------------------------------------
- /**
- * Push game data to SDK
- */
- pushData(data) {
- // Safe extraction of the array
- let itemsArray = [];
- if (Array.isArray(data)) {
- itemsArray = data;
- }
- else if (data && Array.isArray(data.items)) {
- itemsArray = data.items;
- }
- else if (data && Array.isArray(data.data)) {
- itemsArray = data.data;
- }
- else if (data && data.items && typeof data.items === 'object') {
- itemsArray = [data.items];
- }
- else if (data && data.data && typeof data.data === 'object') {
- itemsArray = [data.data];
- }
- // Transform to SDK iframe internal format
- const payload = {
- data: itemsArray,
- completed_question_ids: (data && data.completed_question_ids) || []
- };
- this._send(MSG.PUSH_DATA, payload);
- }
- /**
- * Submit an answer
- */
- submitAnswer(answer) {
- // Transform to SDK iframe format
- const payload = {
- question_id: answer.questionId,
- choice: answer.selectedAnswer,
- time_spent: answer.timeSpent ?? 0
- };
- this._send(MSG.SUBMIT_ANSWER, payload);
- }
- /**
- * Complete the game
- */
- completeGame() {
- this._send(MSG.COMPLETE_GAME, {});
- }
- /**
- * Get current status
- */
- getStatus() {
- this._send(MSG.GET_STATUS, {});
- }
- /**
- * Wait for SDK to be ready
- */
- async ready() {
- if (this.isReady)
- return this;
- return this.initPromise;
- }
- /**
- * Check if SDK is ready
- */
- get sdkReady() {
- return this.isReady;
- }
- /**
- * Check if data is ready
- */
- get dataReady() {
- return this.isDataReady;
- }
- /**
- * Destroy the SDK instance
- */
- destroy() {
- window.removeEventListener('message', this._handleMessage);
- if (this.timeoutId) {
- clearTimeout(this.timeoutId);
- }
- if (this.iframe && this.iframe.parentNode) {
- this.iframe.parentNode.removeChild(this.iframe);
- }
- window.removeEventListener('message', this._handleMessage);
- this.isReady = false;
- this._log('SDK destroyed');
- }
- // ----------------------------------------
- // PRIVATE METHODS
- // ----------------------------------------
- _init() {
- this._log('Initializing SenaGameSDK...');
- // Setup message listener
- window.addEventListener('message', this._handleMessage);
- // Create iframe
- this._createIframe();
- // Setup timeout
- this.timeoutId = setTimeout(() => {
- if (!this.isReady) {
- const error = new Error('SDK initialization timeout');
- this._error(error);
- if (this.initResolver) {
- this.initResolver.reject(error);
- }
- }
- }, this.config.timeout);
- }
- _createIframe() {
- this.iframe = document.createElement('iframe');
- this.iframe.id = 'sena-game-sdk-iframe';
- this.iframe.src = this.config.iframePath;
- this.iframe.style.cssText = this.config.iframeStyle || '';
- this.iframe.onload = () => {
- this._log('Iframe loaded, sending INIT...');
- setTimeout(() => {
- this._send(MSG.INIT, {
- mode: this.config.mode,
- game_code: this.config.gameCode,
- });
- }, 100);
- };
- this.iframe.onerror = () => {
- this._error(new Error('Failed to load SDK iframe'));
- };
- document.body.appendChild(this.iframe);
- this._log(`Iframe created: ${this.config.iframePath}`);
- }
- _send(type, payload) {
- if (!this.iframe || !this.iframe.contentWindow) {
- this._log(`Queuing message: ${type}`, 'warn');
- this.pendingMessages.push({ type, payload });
- return;
- }
- const message = { type, payload, timestamp: Date.now() };
- this._log(`→ ${type}`, 'send');
- this.iframe.contentWindow.postMessage(message, '*');
- }
- _handleMessage(event) {
- const data = event.data;
- if (!data || !data.type)
- return;
- // Only process SDK messages
- if (!data.type.startsWith('SDK_'))
- return;
- this._log(`← ${data.type}`, 'recv');
- switch (data.type) {
- case MSG.READY:
- this._onSDKReady();
- break;
- case MSG.DATA_READY:
- this._onDataReady(data.payload);
- break;
- case MSG.ANSWER_RESULT:
- this._onAnswerResult(data.payload);
- break;
- case MSG.GAME_COMPLETE:
- this._onGameComplete(data.payload);
- break;
- case MSG.SESSION_STARTED:
- this._onSessionStart(data.payload);
- break;
- case MSG.ERROR:
- this._error(new Error(data.payload?.message || 'SDK Error'));
- break;
- }
- }
- _onSDKReady() {
- this.isReady = true;
- if (this.timeoutId) {
- clearTimeout(this.timeoutId);
- this.timeoutId = null;
- }
- // Flush pending messages
- while (this.pendingMessages.length > 0) {
- const msg = this.pendingMessages.shift();
- if (msg) {
- this._send(msg.type, msg.payload);
- }
- }
- // Callback
- if (this.config.onReady) {
- this.config.onReady(this);
- }
- // Resolve promise
- if (this.initResolver) {
- this.initResolver.resolve(this);
- }
- this._log('✅ SDK Ready!');
- }
- _onDataReady(payload) {
- this.isDataReady = true;
- // Normalize payload to camelCase
- const normalized = {
- items: payload.items || [],
- totalQuestions: payload.total_questions || payload.totalQuestions || 0,
- completedCount: payload.completed_count || payload.completedCount || 0,
- resumeData: payload.resume_data || payload.resumeData || []
- };
- if (this.config.onDataReady) {
- this.config.onDataReady(normalized);
- }
- this._log(`✅ Data Ready: ${normalized.items.length} items`);
- }
- _onAnswerResult(payload) {
- const normalized = {
- questionId: payload.question_id || payload.questionId,
- isCorrect: payload.correct !== undefined ? payload.correct : payload.isCorrect,
- correctAnswer: payload.correct_answer || payload.correctAnswer || '',
- score: payload.score || 0,
- currentScore: payload.current_score || payload.currentScore || 0,
- totalAnswered: payload.total_answered || payload.totalAnswered || 0
- };
- if (this.config.onAnswerResult) {
- this.config.onAnswerResult(normalized);
- }
- }
- _onGameComplete(payload) {
- const normalized = {
- success: payload.success !== undefined ? payload.success : true,
- finalScore: payload.score !== undefined ? payload.score : (payload.finalScore || 0),
- correctCount: payload.correct !== undefined ? payload.correct : (payload.correctCount || 0),
- totalQuestions: payload.total !== undefined ? payload.total : (payload.totalQuestions || 0),
- wrongCount: payload.wrong !== undefined ? payload.wrong : (payload.wrongCount || 0),
- total: payload.total || 0
- };
- if (this.config.onGameComplete) {
- this.config.onGameComplete(normalized);
- }
- }
- _onSessionStart(payload) {
- const normalized = {
- assignmentId: payload.assignment_id || payload.assignmentId,
- userId: payload.student_id || payload.userId,
- gameId: payload.game_code || payload.gameId,
- startedAt: payload.started_at || payload.startedAt || new Date().toISOString()
- };
- if (this.config.onSessionStart) {
- this.config.onSessionStart(normalized);
- }
- }
- _error(error) {
- this._log(`❌ Error: ${error.message}`, 'error');
- if (this.config.onError) {
- this.config.onError(error);
- }
- }
- _log(message, type = 'info') {
- if (!this.config.debug)
- return;
- const prefix = '[SenaGameSDK]';
- const styles = {
- info: 'color: #888',
- send: 'color: #ff0',
- recv: 'color: #0f0',
- warn: 'color: #fa0',
- error: 'color: #f00',
- };
- console.log(`%c${prefix} ${message}`, styles[type] || styles.info);
- }
-}
-/** SDK version */
-SenaGameSDK.VERSION = '1.0.0';
-// ========================================
-// EXPORT FOR BROWSER (UMD)
-// ========================================
-if (typeof window !== 'undefined') {
- window.SenaGameSDK = SenaGameSDK;
-}
-export default SenaGameSDK;
-//# sourceMappingURL=SenaGameSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js.map b/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js.map
deleted file mode 100644
index 1fb2660..0000000
--- a/G102-sequence/sdk/package/dist/esm/loader/SenaGameSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SenaGameSDK.js","sourceRoot":"","sources":["../../../src/loader/SenaGameSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/loader/index.js b/G102-sequence/sdk/package/dist/esm/loader/index.js
deleted file mode 100644
index 13f37f4..0000000
--- a/G102-sequence/sdk/package/dist/esm/loader/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * SenaGame SDK Loader
- * Export all types and classes for game developers
- */
-export { SenaGameSDK, } from './SenaGameSDK';
-export { SenaGameSDK as default } from './SenaGameSDK';
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/loader/index.js.map b/G102-sequence/sdk/package/dist/esm/loader/index.js.map
deleted file mode 100644
index 7b1e2dd..0000000
--- a/G102-sequence/sdk/package/dist/esm/loader/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/loader/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,WAAW,GASd,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js b/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js
deleted file mode 100644
index 7646ed3..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js
+++ /dev/null
@@ -1,465 +0,0 @@
-/**
- * SDK Iframe Core
- * Chạy trong hidden iframe riêng biệt
- *
- * Responsibilities:
- * - Receive data từ parent (preview mode)
- * - Fetch data từ API (live mode)
- * - Store answers securely
- * - Verify answers locally (fast feedback)
- * - Sync với server (background)
- * - Report results
- */
-import { checkAnswer, sanitizeForClient, GAME_CODES } from '../kit/GameDataHandler';
-import { getMockData } from '../client/MockData';
-import { SDK_MESSAGE_TYPES, createSdkMessage, isSdkMessage, } from './types';
-// =============================================================================
-// SDK IFRAME CORE
-// =============================================================================
-export class SdkIframeCore {
- constructor(config = {}) {
- this.boundMessageHandler = null;
- this.mode = null;
- this.gameCode = null;
- this.assignmentId = null;
- this.studentId = null;
- this.apiBaseUrl = '';
- this.authToken = '';
- // Data storage
- this.originalItems = new Map(); // Có đáp án
- this.clientItems = new Map(); // Shuffled (cho Client)
- this.sanitizedItems = [];
- this.userAnswers = new Map();
- this.completedQuestions = new Set();
- this.isInitialized = false;
- this.parentOrigin = null;
- this.config = {
- debug: config.debug ?? false,
- allowedOrigins: config.allowedOrigins ?? ['*'],
- };
- this.setupMessageListener();
- this.log('info', 'SDK Iframe Core initialized');
- }
- // ==========================================================================
- // MESSAGE HANDLING
- // ==========================================================================
- setupMessageListener() {
- this.boundMessageHandler = this.handleMessage.bind(this);
- window.addEventListener('message', this.boundMessageHandler);
- }
- handleMessage(event) {
- // Validate origin
- if (!this.isAllowedOrigin(event.origin)) {
- this.log('warn', `Blocked message from unauthorized origin: ${event.origin}`);
- return;
- }
- const data = event.data;
- if (!isSdkMessage(data)) {
- return;
- }
- this.log('debug', `Received: ${data.type}`, data.payload);
- // Store parent origin for responses
- if (!this.parentOrigin) {
- this.parentOrigin = event.origin;
- }
- switch (data.type) {
- case SDK_MESSAGE_TYPES.SDK_INIT:
- this.handleInit(data.payload, data.request_id);
- break;
- case SDK_MESSAGE_TYPES.SDK_PUSH_DATA:
- this.handlePushData(data.payload, data.request_id);
- break;
- case SDK_MESSAGE_TYPES.SDK_CHECK_ANSWER:
- this.handleCheckAnswer(data.payload, data.request_id);
- break;
- case SDK_MESSAGE_TYPES.SDK_GET_RESULT:
- this.handleGetResult(data.request_id);
- break;
- case SDK_MESSAGE_TYPES.SDK_RETRY_SYNC:
- this.handleRetrySync(data.payload, data.request_id);
- break;
- default:
- this.log('warn', `Unknown message type: ${data.type}`);
- }
- }
- isAllowedOrigin(origin) {
- if (this.config.allowedOrigins.includes('*')) {
- return true;
- }
- return this.config.allowedOrigins.includes(origin);
- }
- // ==========================================================================
- // MESSAGE HANDLERS
- // ==========================================================================
- async handleInit(payload, requestId) {
- try {
- this.mode = payload.mode;
- this.gameCode = payload.game_code;
- this.assignmentId = payload.assignment_id ?? null;
- this.studentId = payload.student_id ?? null;
- this.apiBaseUrl = payload.api_base_url ?? '';
- this.authToken = payload.auth_token ?? '';
- // Validate game code
- if (!GAME_CODES[this.gameCode]) {
- throw new Error(`Invalid game code: ${this.gameCode}`);
- }
- this.isInitialized = true;
- // Send ready
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_READY, {
- mode: this.mode,
- game_code: this.gameCode,
- }, requestId);
- this.log('info', `Initialized: mode=${this.mode}, game_code=${this.gameCode}`);
- // Mode handling
- if (this.mode === 'live' && this.assignmentId) {
- await this.fetchLiveData();
- }
- else if (this.mode === 'dev') {
- const mockData = getMockData(this.gameCode);
- if (mockData) {
- this.log('info', `[Dev] Loaded mock data for ${this.gameCode}`);
- this.processData(mockData.data);
- }
- else {
- this.sendError('MOCK_NOT_FOUND', `No mock data found for ${this.gameCode}`, requestId);
- }
- }
- }
- catch (error) {
- this.sendError('INIT_ERROR', error.message, requestId);
- }
- }
- handlePushData(payload, requestId) {
- if (!this.isInitialized) {
- this.sendError('NOT_INITIALIZED', 'SDK not initialized. Call SDK_INIT first.', requestId);
- return;
- }
- if (this.mode !== 'preview') {
- this.sendError('INVALID_MODE', 'SDK_PUSH_DATA only allowed in preview mode', requestId);
- return;
- }
- try {
- this.processData(payload.data, payload.completed_question_ids);
- }
- catch (error) {
- this.sendError('DATA_ERROR', error.message, requestId);
- }
- }
- async handleCheckAnswer(payload, requestId) {
- if (!this.isInitialized || this.originalItems.size === 0) {
- this.sendError('NOT_READY', 'No data loaded', requestId);
- return;
- }
- const { question_id, choice, time_spent = 0 } = payload;
- // ===== RESOLVE CHOICE BY GAME CODE =====
- // Each game code has its own resolution logic
- const code = this.gameCode;
- const clientItem = this.clientItems.get(question_id);
- let answerValue = choice; // Default: use raw choice
- switch (code) {
- // ===== QUIZ VARIANTS (G001-G005): Client sends INDEX -> resolve to VALUE =====
- case 'G001': // Quiz Text-Text
- case 'G002': // Quiz Audio-Text
- case 'G003': // Quiz Text-Audio
- case 'G004': // Quiz Image-Text
- case 'G005': // Quiz Text-Image
- // Sanitizers store __shuffledOptions which contains resolved values (strings)
- if (clientItem && typeof choice === 'number') {
- const shuffled = clientItem.__shuffledOptions;
- if (Array.isArray(shuffled) && choice >= 0 && choice < shuffled.length) {
- answerValue = shuffled[choice];
- this.log('debug', `[${code}] Resolved: index ${choice} -> "${answerValue}"`);
- }
- }
- break;
- // ===== SEQUENCE WORD VARIANTS (G110-G113) =====
- case 'G110': // Sequence Word
- case 'G111': // Sequence Word Audio
- case 'G112': // Sequence Word Audio
- case 'G113': // Sequence Word Audio
- // ===== SEQUENCE SENTENCE VARIANTS (G120-G123) =====
- case 'G120': // Sequence Sentence
- case 'G121': // Sequence Sentence Audio
- case 'G122': // Sequence Sentence Audio
- case 'G123': // Sequence Sentence Audio
- // Client gửi mảng chữ đã sắp xếp ["H","E","L","L","O"]
- // Không cần resolve - so trực tiếp với answer
- this.log('debug', `[${code}] Answer array: ${JSON.stringify(choice)}`);
- break;
- default:
- this.log('warn', `Unknown game code: ${code}, using raw choice`);
- }
- // Get original item
- const originalItem = this.originalItems.get(question_id);
- if (!originalItem) {
- this.sendError('QUESTION_NOT_FOUND', `Question ${question_id} not found`, requestId);
- return;
- }
- // =====================================================================
- // LOCAL VERIFY (Preview / Dev): Verify locally, return immediately
- // =====================================================================
- if (this.mode === 'preview' || this.mode === 'dev') {
- // Verify using RESOLVED VALUE (answerValue)
- const result = checkAnswer(this.gameCode, originalItem, answerValue);
- // Store answer
- const storedAnswer = {
- question_id,
- choice,
- answer_value: answerValue, // Store resolved value for retry
- correct: result.isCorrect,
- score: result.score,
- synced: true, // Local (preview/dev) = always synced
- time_spent,
- };
- this.userAnswers.set(question_id, storedAnswer);
- // Send result immediately
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT, {
- question_id,
- correct: result.isCorrect,
- score: result.score,
- synced: true,
- }, requestId);
- this.log('info', `[Local] Answer checked locally (${this.mode}): ${question_id} = ${result.isCorrect}`);
- return;
- }
- // =====================================================================
- // LIVE MODE: Submit to server, wait for response, then return result
- // =====================================================================
- try {
- // Submit RESOLVED VALUE (answerValue) to server
- const serverResult = await this.submitAnswerToServer(question_id, answerValue, time_spent);
- // Store answer with server result
- const storedAnswer = {
- question_id,
- choice,
- answer_value: answerValue, // Store resolved value for retry
- correct: serverResult.correct,
- score: serverResult.score,
- synced: true,
- time_spent,
- };
- this.userAnswers.set(question_id, storedAnswer);
- // Send result from server
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT, {
- question_id,
- correct: serverResult.correct,
- score: serverResult.score,
- synced: true,
- }, requestId);
- this.log('info', `[Live] Answer verified by server: ${question_id} = ${serverResult.correct}`);
- }
- catch (error) {
- // Server error - send error to game
- this.sendError('SUBMIT_ERROR', error.message || 'Failed to submit answer', requestId);
- this.log('error', `[Live] Failed to submit answer: ${question_id}`, error);
- }
- }
- /**
- * Submit answer to server and wait for result (Live mode)
- */
- async submitAnswerToServer(questionId, choice, timeSpent) {
- if (!this.apiBaseUrl || !this.assignmentId) {
- throw new Error('Missing apiBaseUrl or assignmentId');
- }
- const url = `${this.apiBaseUrl}/submissions/live/answer`;
- const headers = {
- 'Content-Type': 'application/json',
- };
- if (this.authToken) {
- headers['Authorization'] = `Bearer ${this.authToken}`;
- }
- const response = await fetch(url, {
- method: 'POST',
- headers,
- body: JSON.stringify({
- assignment_id: this.assignmentId,
- student_id: this.studentId,
- question_id: questionId,
- selected_answer: choice,
- time_spent: timeSpent,
- is_timeout: false,
- }),
- });
- if (!response.ok) {
- const errorData = await response.json().catch(() => ({}));
- throw new Error(errorData.message || `Server error: ${response.status}`);
- }
- const result = await response.json();
- return {
- correct: result.correct ?? false,
- score: result.score ?? (result.correct ? 1 : 0),
- };
- }
- handleGetResult(requestId) {
- const details = Array.from(this.userAnswers.values()).map(answer => ({
- question_id: answer.question_id,
- choice: answer.choice,
- correct: answer.correct,
- synced: answer.synced,
- time_spent: answer.time_spent,
- }));
- const correct = details.filter(d => d.correct).length;
- const total = this.originalItems.size;
- const allSynced = details.every(d => d.synced);
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_FINAL_RESULT, {
- score: total > 0 ? Math.round((correct / total) * 100) : 0,
- total,
- correct,
- wrong: total - correct,
- synced: allSynced,
- details,
- }, requestId);
- }
- async handleRetrySync(payload, requestId) {
- const answer = this.userAnswers.get(payload.question_id);
- if (!answer) {
- this.sendError('ANSWER_NOT_FOUND', `Answer for ${payload.question_id} not found`, requestId);
- return;
- }
- if (answer.synced) {
- // Already synced
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_SYNC_STATUS, {
- question_id: payload.question_id,
- synced: true,
- }, requestId);
- return;
- }
- // Retry submit to server - use RESOLVED value, not raw choice
- try {
- const serverResult = await this.submitAnswerToServer(answer.question_id, answer.answer_value, // Use resolved value!
- answer.time_spent);
- // Update stored answer
- answer.correct = serverResult.correct;
- answer.score = serverResult.score;
- answer.synced = true;
- // Send success
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_SYNC_STATUS, {
- question_id: payload.question_id,
- synced: true,
- server_result: serverResult,
- }, requestId);
- }
- catch (error) {
- this.sendError('RETRY_ERROR', error.message || 'Retry failed', requestId);
- }
- }
- // ==========================================================================
- // DATA PROCESSING
- // ==========================================================================
- processData(items, completedIds) {
- // Store original items (with answers)
- this.originalItems.clear();
- items.forEach(item => {
- if (item.id) {
- this.originalItems.set(item.id, item);
- }
- });
- // Track completed questions
- this.completedQuestions.clear();
- if (completedIds) {
- completedIds.forEach(q => this.completedQuestions.add(q.id));
- }
- // Sanitize for game (remove answers)
- this.sanitizedItems = sanitizeForClient(this.gameCode, items);
- // Store sanitized items for lookup (to map choice index -> value)
- this.clientItems.clear();
- this.sanitizedItems.forEach(item => {
- if (item.id)
- this.clientItems.set(item.id, item);
- });
- // Send data ready
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_DATA_READY, {
- items: this.sanitizedItems,
- total_questions: items.length,
- completed_count: this.completedQuestions.size,
- resume_data: completedIds,
- });
- this.log('info', `Data processed: ${items.length} items, ${this.completedQuestions.size} completed`);
- }
- // ==========================================================================
- // API CALLS
- // ==========================================================================
- async fetchLiveData() {
- if (!this.apiBaseUrl || !this.assignmentId) {
- this.sendError('CONFIG_ERROR', 'Missing apiBaseUrl or assignmentId for live mode');
- return;
- }
- try {
- const url = `${this.apiBaseUrl}/games/${this.assignmentId}`;
- const headers = {
- 'Content-Type': 'application/json',
- };
- if (this.authToken) {
- headers['Authorization'] = `Bearer ${this.authToken}`;
- }
- this.log('info', `Fetching live data: ${url}`);
- const response = await fetch(url, { headers });
- if (!response.ok) {
- throw new Error(`API Error: ${response.status}`);
- }
- const data = await response.json();
- // Extract items from response
- const items = data.data || data.items || data.questions || [];
- const completedIds = data.completed_question_ids || [];
- this.processData(items, completedIds);
- }
- catch (error) {
- this.log('error', 'Failed to fetch live data', error);
- this.sendError('FETCH_ERROR', error.message);
- }
- }
- // ==========================================================================
- // HELPERS
- // ==========================================================================
- sendToParent(type, payload, requestId) {
- const message = createSdkMessage(type, payload, requestId);
- // NOTE: Khi chạy local file://, event.origin có thể là "null" (string) => postMessage sẽ throw nếu dùng làm targetOrigin
- const origin = this.parentOrigin;
- const targetOrigin = (!origin || origin === 'null') ? '*' : origin;
- window.parent.postMessage(message, targetOrigin);
- this.log('debug', `Sent: ${type}`, payload);
- }
- sendError(code, message, requestId) {
- this.sendToParent(SDK_MESSAGE_TYPES.SDK_ERROR, {
- code,
- message,
- }, requestId);
- this.log('error', `Error: ${code} - ${message}`);
- }
- log(level, message, data) {
- if (!this.config.debug && level === 'debug')
- return;
- const prefix = '[SdkIframe]';
- switch (level) {
- case 'debug':
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
- // ==========================================================================
- // CLEANUP
- // ==========================================================================
- destroy() {
- if (this.boundMessageHandler) {
- window.removeEventListener('message', this.boundMessageHandler);
- this.boundMessageHandler = null;
- }
- this.originalItems.clear();
- this.userAnswers.clear();
- this.log('info', 'SDK Iframe destroyed');
- }
-}
-// Auto-init khi script được load
-if (typeof window !== 'undefined') {
- window.SdkIframe = new SdkIframeCore({
- debug: new URLSearchParams(window.location.search).get('debug') === 'true',
- });
-}
-//# sourceMappingURL=SdkIframeCore.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js.map b/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js.map
deleted file mode 100644
index 8e1c225..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SdkIframeCore.js","sourceRoot":"","sources":["../../../src/sdk-iframe/SdkIframeCore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAY,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACH,iBAAiB,EAYjB,gBAAgB,EAChB,YAAY,GACf,MAAM,SAAS,CAAC;AAsBjB,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,MAAM,OAAO,aAAa;IAoBtB,YAAY,SAA0B,EAAE;QAlBhC,wBAAmB,GAA2C,IAAI,CAAC;QACnE,SAAI,GAAsC,IAAI,CAAC;QAC/C,aAAQ,GAAoB,IAAI,CAAC;QACjC,iBAAY,GAA2B,IAAI,CAAC;QAC5C,cAAS,GAAkB,IAAI,CAAC;QAChC,eAAU,GAAW,EAAE,CAAC;QACxB,cAAS,GAAW,EAAE,CAAC;QAE/B,eAAe;QACP,kBAAa,GAAqB,IAAI,GAAG,EAAE,CAAC,CAAE,YAAY;QAC1D,gBAAW,GAAqB,IAAI,GAAG,EAAE,CAAC,CAAI,wBAAwB;QACtE,mBAAc,GAAU,EAAE,CAAC;QAC3B,gBAAW,GAA8B,IAAI,GAAG,EAAE,CAAC;QACnD,uBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAE5C,kBAAa,GAAG,KAAK,CAAC;QACtB,iBAAY,GAAkB,IAAI,CAAC;QAGvC,IAAI,CAAC,MAAM,GAAG;YACV,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK;YAC5B,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,CAAC,GAAG,CAAC;SACjD,CAAC;QAEF,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IACpD,CAAC;IAED,6EAA6E;IAC7E,mBAAmB;IACnB,6EAA6E;IAErE,oBAAoB;QACxB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjE,CAAC;IAEO,aAAa,CAAC,KAAmB;QACrC,kBAAkB;QAClB,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6CAA6C,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9E,OAAO;QACX,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAE1D,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QACrC,CAAC;QAED,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAChB,KAAK,iBAAiB,CAAC,QAAQ;gBAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACjE,MAAM;YAEV,KAAK,iBAAiB,CAAC,aAAa;gBAChC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAA6B,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACzE,MAAM;YAEV,KAAK,iBAAiB,CAAC,gBAAgB;gBACnC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAgC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/E,MAAM;YAEV,KAAK,iBAAiB,CAAC,cAAc;gBACjC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtC,MAAM;YAEV,KAAK,iBAAiB,CAAC,cAAc;gBACjC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAkC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/E,MAAM;YAEV;gBACI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,yBAAyB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,MAAc;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,6EAA6E;IAC7E,mBAAmB;IACnB,6EAA6E;IAErE,KAAK,CAAC,UAAU,CAAC,OAAuB,EAAE,SAAkB;QAChE,IAAI,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,SAAqB,CAAC;YAC9C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;YAClD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;YAC5C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;YAE1C,qBAAqB;YACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAE1B,aAAa;YACb,IAAI,CAAC,YAAY,CAAkB,iBAAiB,CAAC,SAAS,EAAE;gBAC5D,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,IAAI,CAAC,QAAQ;aAC3B,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAE/E,gBAAgB;YAChB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC5C,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC/B,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,QAAS,CAAC,CAAC;gBAC7C,IAAI,QAAQ,EAAE,CAAC;oBACX,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,8BAA8B,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAChE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,0BAA0B,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC;gBAC3F,CAAC;YACL,CAAC;QAEL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,OAA2B,EAAE,SAAkB;QAClE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,2CAA2C,EAAE,SAAS,CAAC,CAAC;YAC1F,OAAO;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,4CAA4C,EAAE,SAAS,CAAC,CAAC;YACxF,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAA8B,EAAE,SAAkB;QAC9E,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;YACzD,OAAO;QACX,CAAC;QAED,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;QAExD,0CAA0C;QAC1C,8CAA8C;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAS,CAAC;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,WAAW,GAAQ,MAAM,CAAC,CAAE,0BAA0B;QAE1D,QAAQ,IAAI,EAAE,CAAC;YACX,gFAAgF;YAChF,KAAK,MAAM,CAAC,CAAE,iBAAiB;YAC/B,KAAK,MAAM,CAAC,CAAE,kBAAkB;YAChC,KAAK,MAAM,CAAC,CAAE,kBAAkB;YAChC,KAAK,MAAM,CAAC,CAAE,kBAAkB;YAChC,KAAK,MAAM,EAAG,kBAAkB;gBAC5B,8EAA8E;gBAC9E,IAAI,UAAU,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,iBAAiB,CAAC;oBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;wBACrE,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;wBAC/B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,qBAAqB,MAAM,QAAQ,WAAW,GAAG,CAAC,CAAC;oBACjF,CAAC;gBACL,CAAC;gBACD,MAAM;YAEV,iDAAiD;YACjD,KAAK,MAAM,CAAC,CAAE,gBAAgB;YAC9B,KAAK,MAAM,CAAC,CAAE,sBAAsB;YACpC,KAAK,MAAM,CAAC,CAAE,sBAAsB;YACpC,KAAK,MAAM,CAAC,CAAE,sBAAsB;YACpC,qDAAqD;YACrD,KAAK,MAAM,CAAC,CAAE,oBAAoB;YAClC,KAAK,MAAM,CAAC,CAAE,0BAA0B;YACxC,KAAK,MAAM,CAAC,CAAE,0BAA0B;YACxC,KAAK,MAAM,EAAG,0BAA0B;gBACpC,uDAAuD;gBACvD,8CAA8C;gBAC9C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,mBAAmB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvE,MAAM;YAEV;gBACI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,IAAI,oBAAoB,CAAC,CAAC;QACzE,CAAC;QAID,oBAAoB;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,YAAY,WAAW,YAAY,EAAE,SAAS,CAAC,CAAC;YACrF,OAAO;QACX,CAAC;QAED,wEAAwE;QACxE,mEAAmE;QACnE,wEAAwE;QACxE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACjD,4CAA4C;YAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,QAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;YAEtE,eAAe;YACf,MAAM,YAAY,GAAiB;gBAC/B,WAAW;gBACX,MAAM;gBACN,YAAY,EAAE,WAAW,EAAG,iCAAiC;gBAC7D,OAAO,EAAE,MAAM,CAAC,SAAS;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,IAAI,EAAG,sCAAsC;gBACrD,UAAU;aACb,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAEhD,0BAA0B;YAC1B,IAAI,CAAC,YAAY,CAAyB,iBAAiB,CAAC,iBAAiB,EAAE;gBAC3E,WAAW;gBACX,OAAO,EAAE,MAAM,CAAC,SAAS;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,IAAI;aACf,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,IAAI,CAAC,IAAI,MAAM,WAAW,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACxG,OAAO;QACX,CAAC;QAED,wEAAwE;QACxE,qEAAqE;QACrE,wEAAwE;QACxE,IAAI,CAAC;YACD,gDAAgD;YAChD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAE3F,kCAAkC;YAClC,MAAM,YAAY,GAAiB;gBAC/B,WAAW;gBACX,MAAM;gBACN,YAAY,EAAE,WAAW,EAAG,iCAAiC;gBAC7D,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,MAAM,EAAE,IAAI;gBACZ,UAAU;aACb,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAEhD,0BAA0B;YAC1B,IAAI,CAAC,YAAY,CAAyB,iBAAiB,CAAC,iBAAiB,EAAE;gBAC3E,WAAW;gBACX,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,MAAM,EAAE,IAAI;aACf,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,qCAAqC,WAAW,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;QAEnG,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,oCAAoC;YACpC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,IAAI,yBAAyB,EAAE,SAAS,CAAC,CAAC;YACtF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mCAAmC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/E,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAC9B,UAAkB,EAClB,MAAW,EACX,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,0BAA0B,CAAC;QACzD,MAAM,OAAO,GAA2B;YACpC,cAAc,EAAE,kBAAkB;SACrC,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1D,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC9B,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACjB,aAAa,EAAE,IAAI,CAAC,YAAY;gBAChC,UAAU,EAAE,IAAI,CAAC,SAAS;gBAC1B,WAAW,EAAE,UAAU;gBACvB,eAAe,EAAE,MAAM;gBACvB,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,KAAK;aACpB,CAAC;SACL,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,OAAO,IAAI,iBAAiB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAErC,OAAO;YACH,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK;YAChC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAClD,CAAC;IACN,CAAC;IAEO,eAAe,CAAC,SAAkB;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjE,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;SAChC,CAAC,CAAC,CAAC;QAEJ,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACtC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,CAAC,YAAY,CAAwB,iBAAiB,CAAC,gBAAgB,EAAE;YACzE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,KAAK;YACL,OAAO;YACP,KAAK,EAAE,KAAK,GAAG,OAAO;YACtB,MAAM,EAAE,SAAS;YACjB,OAAO;SACV,EAAE,SAAS,CAAC,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,OAAgC,EAAE,SAAkB;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,cAAc,OAAO,CAAC,WAAW,YAAY,EAAE,SAAS,CAAC,CAAC;YAC7F,OAAO;QACX,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,iBAAiB;YACjB,IAAI,CAAC,YAAY,CAAuB,iBAAiB,CAAC,eAAe,EAAE;gBACvE,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,MAAM,EAAE,IAAI;aACf,EAAE,SAAS,CAAC,CAAC;YACd,OAAO;QACX,CAAC;QAED,8DAA8D;QAC9D,IAAI,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAChD,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,YAAY,EAAG,sBAAsB;YAC5C,MAAM,CAAC,UAAU,CACpB,CAAC;YAEF,uBAAuB;YACvB,MAAM,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;YACtC,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;YAClC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YAErB,eAAe;YACf,IAAI,CAAC,YAAY,CAAuB,iBAAiB,CAAC,eAAe,EAAE;gBACvE,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,MAAM,EAAE,IAAI;gBACZ,aAAa,EAAE,YAAY;aAC9B,EAAE,SAAS,CAAC,CAAC;QAElB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,IAAI,cAAc,EAAE,SAAS,CAAC,CAAC;QAC9E,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAErE,WAAW,CAAC,KAAY,EAAE,YAAmD;QACjF,sCAAsC;QACtC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC3B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACjB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACV,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC1C,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,4BAA4B;QAC5B,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAS,EAAE,KAAK,CAAC,CAAC;QAE/D,kEAAkE;QAClE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC/B,IAAI,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,kBAAkB;QAClB,IAAI,CAAC,YAAY,CAAsB,iBAAiB,CAAC,cAAc,EAAE;YACrE,KAAK,EAAE,IAAI,CAAC,cAAc;YAC1B,eAAe,EAAE,KAAK,CAAC,MAAM;YAC7B,eAAe,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI;YAC7C,WAAW,EAAE,YAAY;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,CAAC,MAAM,WAAW,IAAI,CAAC,kBAAkB,CAAC,IAAI,YAAY,CAAC,CAAC;IACzG,CAAC;IAED,6EAA6E;IAC7E,YAAY;IACZ,6EAA6E;IAErE,KAAK,CAAC,aAAa;QACvB,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,kDAAkD,CAAC,CAAC;YACnF,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,UAAU,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5D,MAAM,OAAO,GAA2B;gBACpC,cAAc,EAAE,kBAAkB;aACrC,CAAC;YACF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1D,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,uBAAuB,GAAG,EAAE,CAAC,CAAC;YAE/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEnC,8BAA8B;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,IAAI,EAAE,CAAC;YAEvD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAE1C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,2BAA2B,EAAE,KAAK,CAAC,CAAC;YACtD,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,UAAU;IACV,6EAA6E;IAErE,YAAY,CAAI,IAAY,EAAE,OAAU,EAAE,SAAkB;QAChE,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAW,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAElE,yHAAyH;QACzH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;QACjC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAEjD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAEO,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,SAAkB;QAC/D,IAAI,CAAC,YAAY,CAAkB,iBAAiB,CAAC,SAAS,EAAE;YAC5D,IAAI;YACJ,OAAO;SACV,EAAE,SAAS,CAAC,CAAC;QAEd,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAEO,GAAG,CAAC,KAA0C,EAAE,OAAe,EAAE,IAAU;QAC/E,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO;QAEpD,MAAM,MAAM,GAAG,aAAa,CAAC;QAC7B,QAAQ,KAAK,EAAE,CAAC;YACZ,KAAK,OAAO,CAAC;YACb,KAAK,MAAM;gBACP,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;gBACzC,MAAM;YACV,KAAK,MAAM;gBACP,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC1C,MAAM;YACV,KAAK,OAAO;gBACR,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC3C,MAAM;QACd,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,UAAU;IACV,6EAA6E;IAE7E,OAAO;QACH,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAChE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC7C,CAAC;CACJ;AAYD,iCAAiC;AACjC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAChC,MAAM,CAAC,SAAS,GAAG,IAAI,aAAa,CAAC;QACjC,KAAK,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,MAAM;KAC7E,CAAC,CAAC;AACP,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js b/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js
deleted file mode 100644
index e46ae80..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * SDK Iframe exports
- */
-import { SdkIframeCore } from './SdkIframeCore';
-export * from './types';
-export { SdkIframeCore };
-// Export to window for direct browser usage
-if (typeof window !== 'undefined') {
- window.SdkIframeCore = SdkIframeCore;
-}
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js.map b/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js.map
deleted file mode 100644
index 415ff1c..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sdk-iframe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,4CAA4C;AAC5C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAC/B,MAAc,CAAC,aAAa,GAAG,aAAa,CAAC;AAClD,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js b/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js
deleted file mode 100644
index 3cf4313..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * SDK Iframe Message Types
- * Shared types cho SDK Iframe và Game Bridge
- */
-// =============================================================================
-// MESSAGE TYPES
-// =============================================================================
-export const SDK_MESSAGE_TYPES = {
- // Parent/Game → SDK Iframe
- SDK_INIT: 'SDK_INIT',
- SDK_PUSH_DATA: 'SDK_PUSH_DATA',
- SDK_CHECK_ANSWER: 'SDK_CHECK_ANSWER',
- SDK_GET_RESULT: 'SDK_GET_RESULT',
- SDK_RETRY_SYNC: 'SDK_RETRY_SYNC',
- // SDK Iframe → Parent/Game
- SDK_READY: 'SDK_READY',
- SDK_DATA_READY: 'SDK_DATA_READY',
- SDK_ANSWER_RESULT: 'SDK_ANSWER_RESULT',
- SDK_SYNC_STATUS: 'SDK_SYNC_STATUS',
- SDK_SYNC_ERROR: 'SDK_SYNC_ERROR',
- SDK_FINAL_RESULT: 'SDK_FINAL_RESULT',
- SDK_ERROR: 'SDK_ERROR',
-};
-// =============================================================================
-// HELPER FUNCTIONS
-// =============================================================================
-export function createSdkMessage(type, payload, requestId) {
- return {
- type,
- payload,
- timestamp: Date.now(),
- request_id: requestId,
- };
-}
-export function isSdkMessage(data) {
- return data && typeof data === 'object' && 'type' in data && Object.values(SDK_MESSAGE_TYPES).includes(data.type);
-}
-//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js.map b/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js.map
deleted file mode 100644
index 6ad08c5..0000000
--- a/G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sdk-iframe/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC7B,2BAA2B;IAC3B,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,gBAAgB;IAEhC,2BAA2B;IAC3B,SAAS,EAAE,WAAW;IACtB,cAAc,EAAE,gBAAgB;IAChC,iBAAiB,EAAE,mBAAmB;IACtC,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,kBAAkB;IACpC,SAAS,EAAE,WAAW;CAChB,CAAC;AAyGX,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,MAAM,UAAU,gBAAgB,CAAI,IAAoB,EAAE,OAAU,EAAE,SAAkB;IACpF,OAAO;QACH,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,UAAU,EAAE,SAAS;KACxB,CAAC;AACN,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAS;IAClC,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtH,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/types.js b/G102-sequence/sdk/package/dist/esm/types.js
deleted file mode 100644
index 46b8e68..0000000
--- a/G102-sequence/sdk/package/dist/esm/types.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Game Iframe SDK - Types Definition
- */
-// =============================================================================
-// MESSAGE TYPES
-// =============================================================================
-export const MESSAGE_TYPES = {
- // Parent → Iframe
- SERVER_PUSH_DATA: 'SERVER_PUSH_DATA',
- SERVER_PUSH_LEADERBOARD: 'SERVER_PUSH_LEADERBOARD',
- // Iframe → Parent
- GAME_READY: 'GAME_READY',
- ANSWER_REPORT: 'ANSWER_REPORT',
- FINAL_RESULT: 'FINAL_RESULT',
- GET_LEADERBOARD: 'GET_LEADERBOARD',
-};
-export const DEFAULT_CONFIG = {
- iframeOrigin: '*',
- readyDelay: 500,
- autoSendOnReady: true,
- debug: false,
-};
-//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/types.js.map b/G102-sequence/sdk/package/dist/esm/types.js.map
deleted file mode 100644
index e8854fb..0000000
--- a/G102-sequence/sdk/package/dist/esm/types.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,kBAAkB;IAClB,gBAAgB,EAAE,kBAAkB;IACpC,uBAAuB,EAAE,yBAAyB;IAElD,kBAAkB;IAClB,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,eAAe,EAAE,iBAAiB;CAC5B,CAAC;AAqFX,MAAM,CAAC,MAAM,cAAc,GAAkC;IACzD,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,KAAK;CACf,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js b/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js
deleted file mode 100644
index ef79bd8..0000000
--- a/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * Game Iframe SDK - React Hook
- * Custom hook để sử dụng SDK trong React components
- *
- * @example
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk/react';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const {
- * isReady,
- * sendGameData,
- * sendLeaderboard
- * } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onGameReady: () => console.log('Game ready!'),
- * onAnswerReport: (data) => submitToServer(data),
- * onFinalResult: (data) => showResults(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-import { useEffect, useRef, useState, useCallback } from 'react';
-import { GameIframeSDK } from './GameIframeSDK';
-export function useGameIframeSDK(options) {
- const { iframeRef, iframeOrigin, readyDelay, autoSendOnReady, debug, onGameReady, onAnswerReport, onFinalResult, onLeaderboardRequest, onError, } = options;
- const [isReady, setIsReady] = useState(false);
- const sdkRef = useRef(null);
- // Use refs for callbacks to avoid re-creating SDK when callbacks change
- const callbacksRef = useRef({
- onGameReady,
- onAnswerReport,
- onFinalResult,
- onLeaderboardRequest,
- onError,
- });
- // Update callback refs on each render (no effect re-run)
- callbacksRef.current = {
- onGameReady,
- onAnswerReport,
- onFinalResult,
- onLeaderboardRequest,
- onError,
- };
- // Initialize SDK - only depends on config, NOT callbacks
- useEffect(() => {
- const sdk = new GameIframeSDK({
- iframeOrigin,
- readyDelay,
- autoSendOnReady,
- debug,
- });
- sdkRef.current = sdk;
- // Subscribe to events using refs (stable references)
- const unsubscribers = [];
- unsubscribers.push(sdk.on('gameReady', () => {
- setIsReady(true);
- callbacksRef.current.onGameReady?.();
- }));
- unsubscribers.push(sdk.on('answerReport', (data) => {
- callbacksRef.current.onAnswerReport?.(data);
- }));
- unsubscribers.push(sdk.on('finalResult', (data) => {
- callbacksRef.current.onFinalResult?.(data);
- }));
- unsubscribers.push(sdk.on('leaderboardRequest', (data) => {
- callbacksRef.current.onLeaderboardRequest?.(data.top || 10);
- }));
- unsubscribers.push(sdk.on('error', (err) => {
- callbacksRef.current.onError?.(err);
- }));
- return () => {
- unsubscribers.forEach((unsub) => unsub());
- sdk.destroy();
- sdkRef.current = null;
- };
- }, [iframeOrigin, readyDelay, autoSendOnReady, debug]); // ✅ No callback deps
- // Sync iframe ref with SDK
- useEffect(() => {
- if (sdkRef.current && iframeRef.current) {
- sdkRef.current.setIframe(iframeRef.current);
- }
- }, [iframeRef.current]);
- // Reset ready state when iframe src changes
- useEffect(() => {
- setIsReady(false);
- }, [iframeRef.current?.src]);
- // Memoized methods
- const sendGameData = useCallback((data) => {
- return sdkRef.current?.sendGameData(data) ?? false;
- }, []);
- const sendLeaderboard = useCallback((data) => {
- return sdkRef.current?.sendLeaderboard(data) ?? false;
- }, []);
- const queueGameData = useCallback((data) => {
- sdkRef.current?.queueGameData(data);
- }, []);
- const reloadIframe = useCallback(() => {
- setIsReady(false);
- return sdkRef.current?.reloadIframe() ?? false;
- }, []);
- return {
- sdk: sdkRef.current,
- isReady,
- sendGameData,
- sendLeaderboard,
- queueGameData,
- reloadIframe,
- };
-}
-export default useGameIframeSDK;
-//# sourceMappingURL=useGameIframeSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js.map b/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js.map
deleted file mode 100644
index 7423f46..0000000
--- a/G102-sequence/sdk/package/dist/esm/useGameIframeSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"useGameIframeSDK.js","sourceRoot":"","sources":["../../src/useGameIframeSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts b/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts
deleted file mode 100644
index 58d5649..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Game Bridge
- * Wrapper đơn giản cho game developers để giao tiếp với SDK Iframe
- *
- * Usage:
- * ```typescript
- * import { GameBridge } from 'game-iframe-sdk/game-bridge';
- *
- * const bridge = new GameBridge({
- * sdkIframeUrl: 'https://sdk.sena.tech/sdk-iframe.html',
- * debug: true,
- * });
- *
- * // Init
- * await bridge.init({
- * mode: 'preview',
- * game_code: 'G001',
- * });
- *
- * // Listen for data
- * bridge.on('dataReady', (data) => {
- * renderGame(data.items);
- * });
- *
- * // Check answer
- * bridge.checkAnswer('q1', userChoice).then(result => {
- * showFeedback(result.correct);
- * });
- * ```
- */
-import { SdkInitPayload, SdkPushDataPayload, SdkReadyPayload, SdkDataReadyPayload, SdkAnswerResultPayload, SdkSyncStatusPayload, SdkSyncErrorPayload, SdkFinalResultPayload, SdkErrorPayload } from '../sdk-iframe/types';
-export interface GameBridgeConfig {
- sdkIframeUrl: string;
- debug?: boolean;
- timeout?: number;
-}
-export interface GameBridgeEvents {
- ready: SdkReadyPayload;
- dataReady: SdkDataReadyPayload;
- answerResult: SdkAnswerResultPayload;
- syncStatus: SdkSyncStatusPayload;
- syncError: SdkSyncErrorPayload;
- finalResult: SdkFinalResultPayload;
- error: SdkErrorPayload;
-}
-type EventHandler = (data: T) => void;
-export declare class GameBridge {
- private config;
- private sdkIframe;
- private sdkOrigin;
- private isReady;
- private handlers;
- private pendingRequests;
- private requestCounter;
- constructor(config: GameBridgeConfig);
- /**
- * Create SDK Iframe and initialize
- */
- init(payload: SdkInitPayload): Promise;
- /**
- * Push data (preview mode)
- */
- pushData(payload: SdkPushDataPayload): Promise;
- /**
- * Check answer - returns local result immediately
- * Also triggers server sync in background
- */
- checkAnswer(questionId: string, choice: any, timeSpent?: number): Promise;
- /**
- * Get final result
- */
- getFinalResult(): Promise;
- /**
- * Retry sync for a question
- */
- retrySync(questionId: string): Promise;
- /**
- * Subscribe to events
- */
- on(event: K, handler: EventHandler): () => void;
- /**
- * Unsubscribe from events
- */
- off(event: K, handler: EventHandler): void;
- /**
- * Check if SDK is ready
- */
- isSdkReady(): boolean;
- /**
- * Destroy bridge and cleanup
- */
- destroy(): void;
- private setupMessageListener;
- private handleMessage;
- private emit;
- private sendRequest;
- private log;
-}
-/**
- * Get or create GameBridge instance
- */
-export declare function getGameBridge(config?: GameBridgeConfig): GameBridge;
-/**
- * Destroy GameBridge instance
- */
-export declare function destroyGameBridge(): void;
-export {};
-//# sourceMappingURL=GameBridge.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts.map b/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts.map
deleted file mode 100644
index ef8aa6f..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameBridge.d.ts","sourceRoot":"","sources":["../../src/game-bridge/GameBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAGH,cAAc,EACd,kBAAkB,EAElB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EAGlB,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,YAAY,EAAE,sBAAsB,CAAC;IACrC,UAAU,EAAE,oBAAoB,CAAC;IACjC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,WAAW,EAAE,qBAAqB,CAAC;IACnC,KAAK,EAAE,eAAe,CAAC;CAC1B;AAED,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAMzC,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,QAAQ,CAAkE;IAGlF,OAAO,CAAC,eAAe,CAIR;IAEf,OAAO,CAAC,cAAc,CAAK;gBAEf,MAAM,EAAE,gBAAgB;IAsBpC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAmB7D;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQzE;;;OAGG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IASvG;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAItD;;OAEG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAUlE;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAQtG;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQjG;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,OAAO,IAAI,IAAI;IAwBf,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,aAAa;IA4DrB,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,GAAG;CAiBd;AAQD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAQnE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js b/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js
deleted file mode 100644
index 7e78cd3..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js
+++ /dev/null
@@ -1,298 +0,0 @@
-"use strict";
-/**
- * Game Bridge
- * Wrapper đơn giản cho game developers để giao tiếp với SDK Iframe
- *
- * Usage:
- * ```typescript
- * import { GameBridge } from 'game-iframe-sdk/game-bridge';
- *
- * const bridge = new GameBridge({
- * sdkIframeUrl: 'https://sdk.sena.tech/sdk-iframe.html',
- * debug: true,
- * });
- *
- * // Init
- * await bridge.init({
- * mode: 'preview',
- * game_code: 'G001',
- * });
- *
- * // Listen for data
- * bridge.on('dataReady', (data) => {
- * renderGame(data.items);
- * });
- *
- * // Check answer
- * bridge.checkAnswer('q1', userChoice).then(result => {
- * showFeedback(result.correct);
- * });
- * ```
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GameBridge = void 0;
-exports.getGameBridge = getGameBridge;
-exports.destroyGameBridge = destroyGameBridge;
-const types_1 = require("../sdk-iframe/types");
-// =============================================================================
-// GAME BRIDGE
-// =============================================================================
-class GameBridge {
- constructor(config) {
- this.sdkIframe = null;
- this.sdkOrigin = '';
- this.isReady = false;
- // Event handlers
- this.handlers = new Map();
- // Pending requests (for promise-based API)
- this.pendingRequests = new Map();
- this.requestCounter = 0;
- this.config = {
- sdkIframeUrl: config.sdkIframeUrl,
- debug: config.debug ?? false,
- timeout: config.timeout ?? 10000,
- };
- // Extract origin from SDK URL
- try {
- const url = new URL(this.config.sdkIframeUrl);
- this.sdkOrigin = url.origin;
- }
- catch {
- this.sdkOrigin = '*';
- }
- this.setupMessageListener();
- }
- // ==========================================================================
- // PUBLIC API - Init
- // ==========================================================================
- /**
- * Create SDK Iframe and initialize
- */
- async init(payload) {
- // Create hidden iframe
- this.sdkIframe = document.createElement('iframe');
- this.sdkIframe.src = this.config.sdkIframeUrl;
- this.sdkIframe.style.cssText = 'position:absolute;width:0;height:0;border:0;visibility:hidden;';
- this.sdkIframe.setAttribute('aria-hidden', 'true');
- document.body.appendChild(this.sdkIframe);
- this.log('info', 'SDK Iframe created');
- // Wait for iframe to load
- await new Promise((resolve) => {
- this.sdkIframe.onload = () => resolve();
- });
- // Send init
- return this.sendRequest(types_1.SDK_MESSAGE_TYPES.SDK_INIT, payload);
- }
- /**
- * Push data (preview mode)
- */
- async pushData(payload) {
- return this.sendRequest(types_1.SDK_MESSAGE_TYPES.SDK_PUSH_DATA, payload);
- }
- // ==========================================================================
- // PUBLIC API - Game Actions
- // ==========================================================================
- /**
- * Check answer - returns local result immediately
- * Also triggers server sync in background
- */
- async checkAnswer(questionId, choice, timeSpent) {
- const payload = {
- question_id: questionId,
- choice,
- time_spent: timeSpent,
- };
- return this.sendRequest(types_1.SDK_MESSAGE_TYPES.SDK_CHECK_ANSWER, payload);
- }
- /**
- * Get final result
- */
- async getFinalResult() {
- return this.sendRequest(types_1.SDK_MESSAGE_TYPES.SDK_GET_RESULT, {});
- }
- /**
- * Retry sync for a question
- */
- async retrySync(questionId) {
- return this.sendRequest(types_1.SDK_MESSAGE_TYPES.SDK_RETRY_SYNC, {
- question_id: questionId,
- });
- }
- // ==========================================================================
- // PUBLIC API - Events
- // ==========================================================================
- /**
- * Subscribe to events
- */
- on(event, handler) {
- if (!this.handlers.has(event)) {
- this.handlers.set(event, new Set());
- }
- this.handlers.get(event).add(handler);
- return () => this.off(event, handler);
- }
- /**
- * Unsubscribe from events
- */
- off(event, handler) {
- this.handlers.get(event)?.delete(handler);
- }
- // ==========================================================================
- // PUBLIC API - State
- // ==========================================================================
- /**
- * Check if SDK is ready
- */
- isSdkReady() {
- return this.isReady;
- }
- /**
- * Destroy bridge and cleanup
- */
- destroy() {
- // Clear pending requests
- this.pendingRequests.forEach((pending) => {
- clearTimeout(pending.timeout);
- pending.reject(new Error('Bridge destroyed'));
- });
- this.pendingRequests.clear();
- // Remove iframe
- if (this.sdkIframe && this.sdkIframe.parentNode) {
- this.sdkIframe.parentNode.removeChild(this.sdkIframe);
- }
- this.sdkIframe = null;
- // Clear handlers
- this.handlers.clear();
- this.log('info', 'Bridge destroyed');
- }
- // ==========================================================================
- // INTERNAL - Message Handling
- // ==========================================================================
- setupMessageListener() {
- window.addEventListener('message', this.handleMessage.bind(this));
- }
- handleMessage(event) {
- // Validate origin (if not *)
- if (this.sdkOrigin !== '*' && event.origin !== this.sdkOrigin) {
- return;
- }
- const data = event.data;
- if (!(0, types_1.isSdkMessage)(data)) {
- return;
- }
- this.log('debug', `Received: ${data.type}`, data.payload);
- // Handle pending request response
- if (data.request_id && this.pendingRequests.has(data.request_id)) {
- const pending = this.pendingRequests.get(data.request_id);
- clearTimeout(pending.timeout);
- this.pendingRequests.delete(data.request_id);
- if (data.type === types_1.SDK_MESSAGE_TYPES.SDK_ERROR) {
- pending.reject(data.payload);
- }
- else {
- pending.resolve(data.payload);
- }
- return;
- }
- // Handle events
- switch (data.type) {
- case types_1.SDK_MESSAGE_TYPES.SDK_READY:
- this.isReady = true;
- this.emit('ready', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_DATA_READY:
- this.emit('dataReady', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT:
- this.emit('answerResult', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_SYNC_STATUS:
- this.emit('syncStatus', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_SYNC_ERROR:
- this.emit('syncError', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_FINAL_RESULT:
- this.emit('finalResult', data.payload);
- break;
- case types_1.SDK_MESSAGE_TYPES.SDK_ERROR:
- this.emit('error', data.payload);
- break;
- }
- }
- emit(event, data) {
- this.handlers.get(event)?.forEach(handler => {
- try {
- handler(data);
- }
- catch (err) {
- this.log('error', `Error in ${event} handler`, err);
- }
- });
- }
- // ==========================================================================
- // INTERNAL - Sending Messages
- // ==========================================================================
- sendRequest(type, payload) {
- return new Promise((resolve, reject) => {
- if (!this.sdkIframe?.contentWindow) {
- reject(new Error('SDK Iframe not ready'));
- return;
- }
- const requestId = `req_${++this.requestCounter}_${Date.now()}`;
- const message = (0, types_1.createSdkMessage)(type, payload, requestId);
- // Setup timeout
- const timeout = setTimeout(() => {
- this.pendingRequests.delete(requestId);
- reject(new Error(`Request timeout: ${type}`));
- }, this.config.timeout);
- // Store pending request
- this.pendingRequests.set(requestId, { resolve, reject, timeout });
- // Send message
- this.sdkIframe.contentWindow.postMessage(message, this.sdkOrigin);
- this.log('debug', `Sent: ${type}`, payload);
- });
- }
- log(level, message, data) {
- if (!this.config.debug && level === 'debug')
- return;
- const prefix = '[GameBridge]';
- switch (level) {
- case 'debug':
- case 'info':
- console.log(prefix, message, data ?? '');
- break;
- case 'warn':
- console.warn(prefix, message, data ?? '');
- break;
- case 'error':
- console.error(prefix, message, data ?? '');
- break;
- }
- }
-}
-exports.GameBridge = GameBridge;
-// =============================================================================
-// FACTORY
-// =============================================================================
-let bridgeInstance = null;
-/**
- * Get or create GameBridge instance
- */
-function getGameBridge(config) {
- if (!bridgeInstance && config) {
- bridgeInstance = new GameBridge(config);
- }
- if (!bridgeInstance) {
- throw new Error('GameBridge not initialized. Call with config first.');
- }
- return bridgeInstance;
-}
-/**
- * Destroy GameBridge instance
- */
-function destroyGameBridge() {
- bridgeInstance?.destroy();
- bridgeInstance = null;
-}
-//# sourceMappingURL=GameBridge.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js.map b/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js.map
deleted file mode 100644
index 07de0cf..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/GameBridge.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameBridge.js","sourceRoot":"","sources":["../../src/game-bridge/GameBridge.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/index.d.ts b/G102-sequence/sdk/package/dist/game-bridge/index.d.ts
deleted file mode 100644
index 2b815bc..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/index.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Game Bridge exports
- * Dành cho game developers tích hợp vào game
- */
-export { GameBridge, getGameBridge, destroyGameBridge, type GameBridgeConfig, type GameBridgeEvents, } from './GameBridge';
-export { SDK_MESSAGE_TYPES, type SdkMessageType, type SdkInitPayload, type SdkPushDataPayload, type SdkCheckAnswerPayload, type SdkReadyPayload, type SdkDataReadyPayload, type SdkAnswerResultPayload, type SdkSyncStatusPayload, type SdkSyncErrorPayload, type SdkFinalResultPayload, type SdkErrorPayload, } from '../sdk-iframe/types';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/index.d.ts.map b/G102-sequence/sdk/package/dist/game-bridge/index.d.ts.map
deleted file mode 100644
index cff302b..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/game-bridge/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACH,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,GACvB,MAAM,qBAAqB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/index.js b/G102-sequence/sdk/package/dist/game-bridge/index.js
deleted file mode 100644
index 20b006b..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-"use strict";
-/**
- * Game Bridge exports
- * Dành cho game developers tích hợp vào game
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.SDK_MESSAGE_TYPES = exports.destroyGameBridge = exports.getGameBridge = exports.GameBridge = void 0;
-var GameBridge_1 = require("./GameBridge");
-Object.defineProperty(exports, "GameBridge", { enumerable: true, get: function () { return GameBridge_1.GameBridge; } });
-Object.defineProperty(exports, "getGameBridge", { enumerable: true, get: function () { return GameBridge_1.getGameBridge; } });
-Object.defineProperty(exports, "destroyGameBridge", { enumerable: true, get: function () { return GameBridge_1.destroyGameBridge; } });
-// Re-export types từ sdk-iframe
-var types_1 = require("../sdk-iframe/types");
-Object.defineProperty(exports, "SDK_MESSAGE_TYPES", { enumerable: true, get: function () { return types_1.SDK_MESSAGE_TYPES; } });
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/game-bridge/index.js.map b/G102-sequence/sdk/package/dist/game-bridge/index.js.map
deleted file mode 100644
index 12cd4d0..0000000
--- a/G102-sequence/sdk/package/dist/game-bridge/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/game-bridge/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,2CAMsB;AALlB,wGAAA,UAAU,OAAA;AACV,2GAAA,aAAa,OAAA;AACb,+GAAA,iBAAiB,OAAA;AAKrB,gCAAgC;AAChC,6CAa6B;AAZzB,0GAAA,iBAAiB,OAAA"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/index.d.ts b/G102-sequence/sdk/package/dist/index.d.ts
deleted file mode 100644
index 773d812..0000000
--- a/G102-sequence/sdk/package/dist/index.d.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Game Iframe SDK - Main Entry Point
- *
- * @packageDocumentation
- * @module game-iframe-sdk
- *
- * Architecture:
- * - types.ts: Type definitions
- * - mappers.ts: Data transformation/mapping
- * - EventEmitter.ts: Simple typed event emitter
- * - MessageHandler.ts: Handle incoming messages from iframe
- * - MessageSender.ts: Send messages to iframe
- * - GameIframeSDK.ts: Main SDK (composes above layers)
- * - useGameIframeSDK.ts: React hook
- *
- * @example Browser/Vanilla JS
- * ```typescript
- * import { GameIframeSDK } from 'game-iframe-sdk';
- *
- * const sdk = new GameIframeSDK({
- * iframeOrigin: 'http://senaai.vn:1357',
- * debug: true
- * });
- *
- * sdk.setIframe(document.getElementById('gameIframe'));
- *
- * sdk.on('gameReady', () => {
- * sdk.sendGameData({ game_id: 'xxx', user_id: 'yyy', questions: [...] });
- * });
- * ```
- *
- * @example React
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const { isReady, sendGameData } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onAnswerReport: (data) => submitToServer(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-export { GameIframeSDK, createGameIframeSDK, getGameIframeSDK, destroyGameIframeSDK, } from './GameIframeSDK';
-export { MessageHandler } from './MessageHandler';
-export type { MessageHandlerConfig, MessageHandlerEvents } from './MessageHandler';
-export { MessageSender } from './MessageSender';
-export type { MessageSenderConfig, SendResult } from './MessageSender';
-export { EventEmitter } from './EventEmitter';
-export { useGameIframeSDK } from './useGameIframeSDK';
-export type { UseGameIframeSDKOptions, UseGameIframeSDKReturn } from './useGameIframeSDK';
-export { MESSAGE_TYPES, type MessageType, type PushDataPayload, type CompletedQuestionInfo, type AnswerReportData, type FinalResultData, type LeaderboardPlayer, type LeaderboardData, type GameIframeSDKConfig, DEFAULT_CONFIG, type SDKEvents, type SDKEventName, type SDKEventHandler, } from './types';
-import * as Kit from './kit';
-export { Kit };
-import * as Client from './client';
-export { Client };
-export { GameClientSDK, getGameClientSDK, destroyGameClientSDK, type ClientMode, type ClientSDKConfig, type URLParams, type GameDataPayload, type AnswerResult as ClientAnswerResult, type FinalResult as ClientFinalResult, type ClientSDKEvents, } from './client';
-import * as SdkIframe from './sdk-iframe';
-export { SdkIframe };
-export { SdkIframeCore, SDK_MESSAGE_TYPES, type SdkMessageType, type SdkMessage, type SdkInitPayload, type SdkPushDataPayload, type SdkCheckAnswerPayload, type SdkReadyPayload, type SdkDataReadyPayload, type SdkAnswerResultPayload, type SdkSyncStatusPayload, type SdkSyncErrorPayload, type SdkFinalResultPayload, type SdkErrorPayload, } from './sdk-iframe';
-import * as GameBridgeModule from './game-bridge';
-export { GameBridgeModule };
-export { GameBridge, getGameBridge, destroyGameBridge, type GameBridgeConfig, type GameBridgeEvents, } from './game-bridge';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/index.d.ts.map b/G102-sequence/sdk/package/dist/index.d.ts.map
deleted file mode 100644
index 7e49c84..0000000
--- a/G102-sequence/sdk/package/dist/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,OAAO,EACH,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAM1F,OAAO,EAEH,aAAa,EACb,KAAK,WAAW,EAGhB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAG1B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAGpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAGpB,KAAK,mBAAmB,EACxB,cAAc,EAGd,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,eAAe,GACvB,MAAM,SAAS,CAAC;AAMjB,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,CAAC;AAMf,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,IAAI,kBAAkB,EACvC,KAAK,WAAW,IAAI,iBAAiB,EACrC,KAAK,eAAe,GACvB,MAAM,UAAU,CAAC;AAMlB,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,GACvB,MAAM,cAAc,CAAC;AAMtB,OAAO,KAAK,gBAAgB,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,OAAO,EACH,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACxB,MAAM,eAAe,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/index.js b/G102-sequence/sdk/package/dist/index.js
deleted file mode 100644
index 2d16d20..0000000
--- a/G102-sequence/sdk/package/dist/index.js
+++ /dev/null
@@ -1,147 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Main Entry Point
- *
- * @packageDocumentation
- * @module game-iframe-sdk
- *
- * Architecture:
- * - types.ts: Type definitions
- * - mappers.ts: Data transformation/mapping
- * - EventEmitter.ts: Simple typed event emitter
- * - MessageHandler.ts: Handle incoming messages from iframe
- * - MessageSender.ts: Send messages to iframe
- * - GameIframeSDK.ts: Main SDK (composes above layers)
- * - useGameIframeSDK.ts: React hook
- *
- * @example Browser/Vanilla JS
- * ```typescript
- * import { GameIframeSDK } from 'game-iframe-sdk';
- *
- * const sdk = new GameIframeSDK({
- * iframeOrigin: 'http://senaai.vn:1357',
- * debug: true
- * });
- *
- * sdk.setIframe(document.getElementById('gameIframe'));
- *
- * sdk.on('gameReady', () => {
- * sdk.sendGameData({ game_id: 'xxx', user_id: 'yyy', questions: [...] });
- * });
- * ```
- *
- * @example React
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const { isReady, sendGameData } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onAnswerReport: (data) => submitToServer(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() { return m[k]; } };
- }
- Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || (function () {
- var ownKeys = function(o) {
- ownKeys = Object.getOwnPropertyNames || function (o) {
- var ar = [];
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
- return ar;
- };
- return ownKeys(o);
- };
- return function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
- __setModuleDefault(result, mod);
- return result;
- };
-})();
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.destroyGameBridge = exports.getGameBridge = exports.GameBridge = exports.GameBridgeModule = exports.SDK_MESSAGE_TYPES = exports.SdkIframeCore = exports.SdkIframe = exports.destroyGameClientSDK = exports.getGameClientSDK = exports.GameClientSDK = exports.Client = exports.Kit = exports.DEFAULT_CONFIG = exports.MESSAGE_TYPES = exports.useGameIframeSDK = exports.EventEmitter = exports.MessageSender = exports.MessageHandler = exports.destroyGameIframeSDK = exports.getGameIframeSDK = exports.createGameIframeSDK = exports.GameIframeSDK = void 0;
-// =============================================================================
-// CORE SDK
-// =============================================================================
-var GameIframeSDK_1 = require("./GameIframeSDK");
-Object.defineProperty(exports, "GameIframeSDK", { enumerable: true, get: function () { return GameIframeSDK_1.GameIframeSDK; } });
-Object.defineProperty(exports, "createGameIframeSDK", { enumerable: true, get: function () { return GameIframeSDK_1.createGameIframeSDK; } });
-Object.defineProperty(exports, "getGameIframeSDK", { enumerable: true, get: function () { return GameIframeSDK_1.getGameIframeSDK; } });
-Object.defineProperty(exports, "destroyGameIframeSDK", { enumerable: true, get: function () { return GameIframeSDK_1.destroyGameIframeSDK; } });
-// =============================================================================
-// LAYERS (for advanced usage)
-// =============================================================================
-var MessageHandler_1 = require("./MessageHandler");
-Object.defineProperty(exports, "MessageHandler", { enumerable: true, get: function () { return MessageHandler_1.MessageHandler; } });
-var MessageSender_1 = require("./MessageSender");
-Object.defineProperty(exports, "MessageSender", { enumerable: true, get: function () { return MessageSender_1.MessageSender; } });
-var EventEmitter_1 = require("./EventEmitter");
-Object.defineProperty(exports, "EventEmitter", { enumerable: true, get: function () { return EventEmitter_1.EventEmitter; } });
-// Mappers removed - mapped data should be handled by the application
-// =============================================================================
-// =============================================================================
-// REACT HOOK
-// =============================================================================
-var useGameIframeSDK_1 = require("./useGameIframeSDK");
-Object.defineProperty(exports, "useGameIframeSDK", { enumerable: true, get: function () { return useGameIframeSDK_1.useGameIframeSDK; } });
-// =============================================================================
-// TYPES
-// =============================================================================
-var types_1 = require("./types");
-// Message Types
-Object.defineProperty(exports, "MESSAGE_TYPES", { enumerable: true, get: function () { return types_1.MESSAGE_TYPES; } });
-Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return types_1.DEFAULT_CONFIG; } });
-// =============================================================================
-// KIT (Helper Mappers, API, Components)
-// =============================================================================
-const Kit = __importStar(require("./kit"));
-exports.Kit = Kit;
-// =============================================================================
-// CLIENT SDK (for Game Iframe - used by game developers)
-// =============================================================================
-const Client = __importStar(require("./client"));
-exports.Client = Client;
-var client_1 = require("./client");
-Object.defineProperty(exports, "GameClientSDK", { enumerable: true, get: function () { return client_1.GameClientSDK; } });
-Object.defineProperty(exports, "getGameClientSDK", { enumerable: true, get: function () { return client_1.getGameClientSDK; } });
-Object.defineProperty(exports, "destroyGameClientSDK", { enumerable: true, get: function () { return client_1.destroyGameClientSDK; } });
-// =============================================================================
-// SDK IFRAME (Hidden iframe - runs on separate domain for security)
-// =============================================================================
-const SdkIframe = __importStar(require("./sdk-iframe"));
-exports.SdkIframe = SdkIframe;
-var sdk_iframe_1 = require("./sdk-iframe");
-Object.defineProperty(exports, "SdkIframeCore", { enumerable: true, get: function () { return sdk_iframe_1.SdkIframeCore; } });
-Object.defineProperty(exports, "SDK_MESSAGE_TYPES", { enumerable: true, get: function () { return sdk_iframe_1.SDK_MESSAGE_TYPES; } });
-// =============================================================================
-// GAME BRIDGE (For game developers - communicates with SDK Iframe)
-// =============================================================================
-const GameBridgeModule = __importStar(require("./game-bridge"));
-exports.GameBridgeModule = GameBridgeModule;
-var game_bridge_1 = require("./game-bridge");
-Object.defineProperty(exports, "GameBridge", { enumerable: true, get: function () { return game_bridge_1.GameBridge; } });
-Object.defineProperty(exports, "getGameBridge", { enumerable: true, get: function () { return game_bridge_1.getGameBridge; } });
-Object.defineProperty(exports, "destroyGameBridge", { enumerable: true, get: function () { return game_bridge_1.destroyGameBridge; } });
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/index.js.map b/G102-sequence/sdk/package/dist/index.js.map
deleted file mode 100644
index 68b7e7a..0000000
--- a/G102-sequence/sdk/package/dist/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAEhF,iDAKyB;AAJrB,8GAAA,aAAa,OAAA;AACb,oHAAA,mBAAmB,OAAA;AACnB,iHAAA,gBAAgB,OAAA;AAChB,qHAAA,oBAAoB,OAAA;AAGxB,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AAGvB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAGtB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AAErB,qEAAqE;AACrE,gFAAgF;AAEhF,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAGzB,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,iCAyBiB;AAxBb,gBAAgB;AAChB,sGAAA,aAAa,OAAA;AAiBb,uGAAA,cAAc,OAAA;AAQlB,gFAAgF;AAChF,wCAAwC;AACxC,gFAAgF;AAEhF,2CAA6B;AACpB,kBAAG;AAEZ,gFAAgF;AAChF,yDAAyD;AACzD,gFAAgF;AAEhF,iDAAmC;AAC1B,wBAAM;AAEf,mCAWkB;AAVd,uGAAA,aAAa,OAAA;AACb,0GAAA,gBAAgB,OAAA;AAChB,8GAAA,oBAAoB,OAAA;AAUxB,gFAAgF;AAChF,oEAAoE;AACpE,gFAAgF;AAEhF,wDAA0C;AACjC,8BAAS;AAElB,2CAesB;AAdlB,2GAAA,aAAa,OAAA;AACb,+GAAA,iBAAiB,OAAA;AAerB,gFAAgF;AAChF,mEAAmE;AACnE,gFAAgF;AAEhF,gEAAkD;AACzC,4CAAgB;AAEzB,6CAMuB;AALnB,yGAAA,UAAU,OAAA;AACV,4GAAA,aAAa,OAAA;AACb,gHAAA,iBAAiB,OAAA"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts b/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts
deleted file mode 100644
index dc315f7..0000000
--- a/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * GameDataHandler - Data Sanitizer & Scorer
- *
- * Game Codes:
- * - G001: Quiz text-text
- * - G002: Quiz audio-text (audio question, text answer)
- * - G003: Quiz text-audio (text question, audio answer)
- * - G004: Quiz image-text (image question, text answer)
- * - G005: Quiz text-image (text question, image answer)
- *
- * - G110: Sequence Word - no audio
- * - G111: Sequence Word - có audio, missing_letter_count từ item
- * - G112: Sequence Word - có audio, missing_letter_count từ item
- * - G113: Sequence Word - có audio, missing_letter_count từ item
- *
- * - G120: Sequence Sentence - no audio
- * - G121: Sequence Sentence - có audio, missing_letter_count từ item
- * - G122: Sequence Sentence - có audio, missing_letter_count từ item
- * - G123: Sequence Sentence - có audio, missing_letter_count từ item
- */
-export type GameCode = 'G001' | 'G002' | 'G003' | 'G004' | 'G005' | 'G110' | 'G111' | 'G112' | 'G113' | 'G120' | 'G121' | 'G122' | 'G123';
-export declare const GAME_CODES: {
- readonly G001: {
- readonly name: "Quiz Text-Text";
- readonly category: "quiz";
- readonly hasAudio: false;
- readonly hasImage: false;
- };
- readonly G002: {
- readonly name: "Quiz Audio-Text";
- readonly category: "quiz";
- readonly hasAudio: true;
- readonly hasImage: false;
- };
- readonly G003: {
- readonly name: "Quiz Text-Audio";
- readonly category: "quiz";
- readonly hasAudio: true;
- readonly hasImage: false;
- };
- readonly G004: {
- readonly name: "Quiz Image-Text";
- readonly category: "quiz";
- readonly hasAudio: false;
- readonly hasImage: true;
- };
- readonly G005: {
- readonly name: "Quiz Text-Image";
- readonly category: "quiz";
- readonly hasAudio: false;
- readonly hasImage: true;
- };
- readonly G110: {
- readonly name: "Sequence Word";
- readonly category: "sequence_word";
- readonly hasAudio: false;
- };
- readonly G111: {
- readonly name: "Sequence Word Audio";
- readonly category: "sequence_word";
- readonly hasAudio: true;
- };
- readonly G112: {
- readonly name: "Sequence Word Audio";
- readonly category: "sequence_word";
- readonly hasAudio: true;
- };
- readonly G113: {
- readonly name: "Sequence Word Audio";
- readonly category: "sequence_word";
- readonly hasAudio: true;
- };
- readonly G120: {
- readonly name: "Sequence Sentence";
- readonly category: "sequence_sentence";
- readonly hasAudio: false;
- };
- readonly G121: {
- readonly name: "Sequence Sentence Audio";
- readonly category: "sequence_sentence";
- readonly hasAudio: true;
- };
- readonly G122: {
- readonly name: "Sequence Sentence Audio";
- readonly category: "sequence_sentence";
- readonly hasAudio: true;
- };
- readonly G123: {
- readonly name: "Sequence Sentence Audio";
- readonly category: "sequence_sentence";
- readonly hasAudio: true;
- };
-};
-export declare function getGameCategory(code: GameCode): string;
-/**
- * Sanitize game data before sending to iframe
- * CRITICAL: Never send answers/correct data to client
- */
-export declare function sanitizeForClient(code: GameCode, items: any[]): any[];
-export interface AnswerCheckResult {
- isCorrect: boolean;
- score: number;
- feedback?: string;
-}
-/**
- * Check if player's answer is correct
- *
- * @param code - Game code (G001, G110, etc.)
- * @param originalItem - Original item from server (has answer field!)
- * @param playerAnswer - Player's answer (text for quiz, array for sequence)
- */
-export declare function checkAnswer(code: GameCode, originalItem: any, playerAnswer: any): AnswerCheckResult;
-//# sourceMappingURL=GameDataHandler.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts.map b/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts.map
deleted file mode 100644
index 7070bc3..0000000
--- a/G102-sequence/sdk/package/dist/kit/GameDataHandler.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameDataHandler.d.ts","sourceRoot":"","sources":["../../src/kit/GameDataHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,MAAM,MAAM,QAAQ,GAEd,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAE1C,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAEjC,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAGxC,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmBb,CAAC;AAEX,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEtD;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAkDrE;AAwSD,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,GAAG,iBAAiB,CA4BnG"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/GameDataHandler.js b/G102-sequence/sdk/package/dist/kit/GameDataHandler.js
deleted file mode 100644
index a03fe03..0000000
--- a/G102-sequence/sdk/package/dist/kit/GameDataHandler.js
+++ /dev/null
@@ -1,450 +0,0 @@
-"use strict";
-/**
- * GameDataHandler - Data Sanitizer & Scorer
- *
- * Game Codes:
- * - G001: Quiz text-text
- * - G002: Quiz audio-text (audio question, text answer)
- * - G003: Quiz text-audio (text question, audio answer)
- * - G004: Quiz image-text (image question, text answer)
- * - G005: Quiz text-image (text question, image answer)
- *
- * - G110: Sequence Word - no audio
- * - G111: Sequence Word - có audio, missing_letter_count từ item
- * - G112: Sequence Word - có audio, missing_letter_count từ item
- * - G113: Sequence Word - có audio, missing_letter_count từ item
- *
- * - G120: Sequence Sentence - no audio
- * - G121: Sequence Sentence - có audio, missing_letter_count từ item
- * - G122: Sequence Sentence - có audio, missing_letter_count từ item
- * - G123: Sequence Sentence - có audio, missing_letter_count từ item
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GAME_CODES = void 0;
-exports.getGameCategory = getGameCategory;
-exports.sanitizeForClient = sanitizeForClient;
-exports.checkAnswer = checkAnswer;
-// Game code metadata
-exports.GAME_CODES = {
- // Quiz
- G001: { name: 'Quiz Text-Text', category: 'quiz', hasAudio: false, hasImage: false },
- G002: { name: 'Quiz Audio-Text', category: 'quiz', hasAudio: true, hasImage: false },
- G003: { name: 'Quiz Text-Audio', category: 'quiz', hasAudio: true, hasImage: false },
- G004: { name: 'Quiz Image-Text', category: 'quiz', hasAudio: false, hasImage: true },
- G005: { name: 'Quiz Text-Image', category: 'quiz', hasAudio: false, hasImage: true },
- // Sequence Word
- G110: { name: 'Sequence Word', category: 'sequence_word', hasAudio: false },
- G111: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- G112: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- G113: { name: 'Sequence Word Audio', category: 'sequence_word', hasAudio: true },
- // Sequence Sentence
- G120: { name: 'Sequence Sentence', category: 'sequence_sentence', hasAudio: false },
- G121: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
- G122: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
- G123: { name: 'Sequence Sentence Audio', category: 'sequence_sentence', hasAudio: true },
-};
-function getGameCategory(code) {
- return exports.GAME_CODES[code]?.category || 'unknown';
-}
-// =============================================================================
-// SANITIZE DATA FOR CLIENT (REMOVE ANSWERS)
-// =============================================================================
-/**
- * Sanitize game data before sending to iframe
- * CRITICAL: Never send answers/correct data to client
- */
-function sanitizeForClient(code, items) {
- if (!Array.isArray(items))
- return [];
- switch (code) {
- // ===== QUIZ VARIANTS =====
- case 'G001': // Quiz text-text
- return sanitizeQuizTextText(items);
- case 'G002': // Quiz audio-text
- return sanitizeQuizAudioText(items);
- case 'G003': // Quiz text-audio
- return sanitizeQuizTextAudio(items);
- case 'G004': // Quiz image-text
- return sanitizeQuizImageText(items);
- case 'G005': // Quiz text-image
- return sanitizeQuizTextImage(items);
- // ===== SEQUENCE WORD VARIANTS =====
- case 'G110': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G111': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G112': // Sequence word
- return sanitizeSequenceWord(items);
- case 'G113': // Sequence word
- return sanitizeSequenceWord(items);
- // ===== SEQUENCE SENTENCE VARIANTS =====
- case 'G120': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G121': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G122': // Sequence sentence
- return sanitizeSequenceSentence(items);
- case 'G123': // Sequence sentence
- return sanitizeSequenceSentence(items);
- default:
- console.warn(`[GameDataHandler] Unknown game code: ${code}, returning raw data`);
- return items;
- }
-}
-// =============================================================================
-// QUIZ SANITIZERS
-// =============================================================================
-/**
- * G001: Quiz Text-Text
- * Client receives: id, question, options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextText(items) {
- return items.map(item => {
- // Normalize options to {text: string}
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- // Shuffle to hide answer position
- shuffleArray(options);
- // Save shuffled text order for SDK to resolve index
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledTexts, // SDK internal
- };
- });
-}
-/**
- * G002: Quiz Audio-Text
- * Client receives: id, question (audio URL), options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizAudioText(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- question: item.audio || item.audio_url,
- options: options,
- __shuffledOptions: shuffledTexts,
- };
- });
-}
-/**
- * G003: Quiz Text-Audio
- * Client receives: id, question (text), options (audio URLs shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextAudio(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { audio: o };
- }
- if (o && typeof o === 'object') {
- const audioUrl = o.audio || o.audio_url || '';
- return { audio: String(audioUrl) };
- }
- return { audio: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledAudios = options.map((o) => String(o.audio ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledAudios,
- };
- });
-}
-/**
- * G004: Quiz Image-Text
- * Client receives: id, image_url, question (hint), options (shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizImageText(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { text: o };
- }
- if (o && typeof o === 'object') {
- return { text: String(o.text ?? '') };
- }
- return { text: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledTexts = options.map((o) => String(o.text ?? ''));
- return {
- id: item.id,
- image_url: item.image_url,
- question: item.question,
- options: options,
- __shuffledOptions: shuffledTexts,
- };
- });
-}
-/**
- * G005: Quiz Text-Image
- * Client receives: id, question (text), options (image URLs shuffled)
- * Client does NOT receive: answer
- */
-function sanitizeQuizTextImage(items) {
- return items.map(item => {
- const options = (item.options || []).map((o) => {
- if (typeof o === 'string') {
- return { image_url: o };
- }
- if (o && typeof o === 'object') {
- const imageUrl = o.image_url || o.image || '';
- return { image_url: String(imageUrl) };
- }
- return { image_url: String(o ?? '') };
- });
- shuffleArray(options);
- const shuffledUrls = options.map((o) => String(o.image_url ?? ''));
- return {
- id: item.id,
- question: item.question,
- options: options, // Each option has {image_url: ...}
- __shuffledOptions: shuffledUrls,
- };
- });
-}
-// =============================================================================
-// SEQUENCE WORD SANITIZERS
-// =============================================================================
-/**
- * Sequence Word (G110-G113)
- * Client receives: id, question (array with blanks), options (missing letters shuffled), audio_url (optional)
- * Client does NOT receive: word, parts, answer, missing_letter_count
- *
- * Logic:
- * 1. Read missing_letter_count from item (count of letters to blank out)
- * 2. Randomly select positions to blank
- * 3. question: array with blanks at selected positions
- * 4. options: extracted missing letters (shuffled)
- */
-function sanitizeSequenceWord(items) {
- return items.map(item => {
- const parts = item.answer || item.parts || [];
- const missingCount = item.missing_letter_count || 0;
- if (missingCount === 0 || parts.length === 0) {
- // No missing - all visible
- return {
- id: item.id,
- question: [...parts],
- options: [],
- ...(item.audio_url && { audio_url: item.audio_url })
- };
- }
- // Randomly select which positions to blank
- const allIndices = Array.from({ length: parts.length }, (_, i) => i);
- const blankIndices = new Set();
- const count = Math.min(missingCount, parts.length);
- while (blankIndices.size < count) {
- const randomIdx = Math.floor(Math.random() * allIndices.length);
- const actualIdx = allIndices[randomIdx];
- blankIndices.add(actualIdx);
- allIndices.splice(randomIdx, 1);
- }
- // Build question array with blanks at random positions
- const question = parts.map((p, i) => blankIndices.has(i) ? "" : String(p));
- // Extract missing letters and shuffle
- const missingLetters = Array.from(blankIndices).map(i => String(parts[i]));
- shuffleArray(missingLetters);
- const result = {
- id: item.id,
- question, // e.g. ["H", "", "L", "", "O"]
- options: missingLetters, // e.g. ["L", "E"] - shuffled
- __shuffledOptions: [...missingLetters] // SDK internal: to resolve indices
- };
- if (item.audio_url) {
- result.audio_url = item.audio_url;
- }
- // CRITICAL: Do NOT send word, parts, answer, missing_letter_count
- return result;
- });
-}
-// =============================================================================
-// SEQUENCE SENTENCE SANITIZERS
-// =============================================================================
-/**
- * Sequence Sentence (G120-G123)
- * Client receives: id, question (array with blanks), options (missing words shuffled), audio_url (optional)
- * Client does NOT receive: sentence, parts, answer, missing_letter_count
- *
- * Logic: Same as Sequence Word
- * 1. Read missing_letter_count from item
- * 2. Randomly select positions to blank
- * 3. question: array with blanks
- * 4. options: extracted missing words (shuffled)
- */
-function sanitizeSequenceSentence(items) {
- return items.map(item => {
- const parts = item.answer || item.parts || [];
- const missingCount = item.missing_letter_count || 0;
- if (missingCount === 0 || parts.length === 0) {
- // No missing - all visible
- return {
- id: item.id,
- question: [...parts],
- options: [],
- ...(item.audio_url && { audio_url: item.audio_url })
- };
- }
- // Randomly select which positions to blank
- const allIndices = Array.from({ length: parts.length }, (_, i) => i);
- const blankIndices = new Set();
- const count = Math.min(missingCount, parts.length);
- while (blankIndices.size < count) {
- const randomIdx = Math.floor(Math.random() * allIndices.length);
- const actualIdx = allIndices[randomIdx];
- blankIndices.add(actualIdx);
- allIndices.splice(randomIdx, 1);
- }
- // Build question array with blanks at random positions
- const question = parts.map((p, i) => blankIndices.has(i) ? "" : String(p));
- // Extract missing words and shuffle
- const missingWords = Array.from(blankIndices).map(i => String(parts[i]));
- shuffleArray(missingWords);
- const result = {
- id: item.id,
- question, // e.g. ["I", "", "reading", ""]
- options: missingWords, // e.g. ["love", "books"] - shuffled
- __shuffledOptions: [...missingWords] // SDK internal
- };
- if (item.audio_url) {
- result.audio_url = item.audio_url;
- }
- // CRITICAL: Do NOT send sentence, parts, answer, missing_letter_count
- return result;
- });
-}
-/**
- * Check if player's answer is correct
- *
- * @param code - Game code (G001, G110, etc.)
- * @param originalItem - Original item from server (has answer field!)
- * @param playerAnswer - Player's answer (text for quiz, array for sequence)
- */
-function checkAnswer(code, originalItem, playerAnswer) {
- switch (code) {
- // ===== QUIZ VARIANTS (G001-G005) =====
- case 'G001': // Quiz Text-Text
- case 'G002': // Quiz Audio-Text
- case 'G003': // Quiz Text-Audio
- case 'G004': // Quiz Image-Text
- case 'G005': // Quiz Text-Image
- return checkQuizAnswer(originalItem, playerAnswer);
- // ===== SEQUENCE WORD VARIANTS (G110-G113) =====
- case 'G110': // Sequence Word
- case 'G111': // Sequence Word Audio
- case 'G112': // Sequence Word Audio
- case 'G113': // Sequence Word Audio
- return checkSequenceAnswer(originalItem, playerAnswer);
- // ===== SEQUENCE SENTENCE VARIANTS (G120-G123) =====
- case 'G120': // Sequence Sentence
- case 'G121': // Sequence Sentence Audio
- case 'G122': // Sequence Sentence Audio
- case 'G123': // Sequence Sentence Audio
- return checkSequenceAnswer(originalItem, playerAnswer);
- default:
- console.warn(`[GameDataHandler] Unknown game code for scoring: ${code}`);
- return { isCorrect: false, score: 0 };
- }
-}
-// Quiz Scoring
-function checkQuizAnswer(item, answerChoice) {
- const correctAnswer = String(item.answer || '');
- if (!correctAnswer) {
- return { isCorrect: false, score: 0, feedback: 'No correct answer defined' };
- }
- let playerAnswerText;
- if (typeof answerChoice === 'number') {
- // Index: resolve from original options
- if (Array.isArray(item.options)) {
- const v = item.options[answerChoice];
- if (typeof v === 'string') {
- playerAnswerText = v;
- }
- else if (v && typeof v === 'object' && 'text' in v) {
- playerAnswerText = String(v.text ?? '');
- }
- else {
- playerAnswerText = String(v ?? '');
- }
- }
- else {
- return { isCorrect: false, score: 0, feedback: 'Invalid question options' };
- }
- }
- else {
- // Direct text answer
- if (answerChoice && typeof answerChoice === 'object' && 'text' in answerChoice) {
- playerAnswerText = String(answerChoice.text ?? '');
- }
- else {
- playerAnswerText = String(answerChoice ?? '');
- }
- }
- const isCorrect = playerAnswerText.toLowerCase().trim() === correctAnswer.toLowerCase().trim();
- return {
- isCorrect,
- score: isCorrect ? 1 : 0,
- feedback: isCorrect
- ? `✅ Correct! "${playerAnswerText}" matches answer "${correctAnswer}"`
- : `❌ Wrong. You chose "${playerAnswerText}" but correct answer is "${correctAnswer}"`
- };
-}
-// Sequence Scoring
-function checkSequenceAnswer(item, answer) {
- const correctOrder = item.answer || item.parts;
- if (!Array.isArray(answer) || !Array.isArray(correctOrder)) {
- return { isCorrect: false, score: 0 };
- }
- const isCorrect = arraysEqual(answer, correctOrder);
- return {
- isCorrect,
- score: isCorrect ? 1 : 0,
- };
-}
-// =============================================================================
-// UTILITIES
-// =============================================================================
-function shuffleArray(array) {
- for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- [array[i], array[j]] = [array[j], array[i]];
- }
-}
-function arraysEqual(a, b) {
- if (a.length !== b.length)
- return false;
- return a.every((val, idx) => {
- if (typeof val === 'string' && typeof b[idx] === 'string') {
- return val.toLowerCase().trim() === b[idx].toLowerCase().trim();
- }
- return val === b[idx];
- });
-}
-//# sourceMappingURL=GameDataHandler.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/GameDataHandler.js.map b/G102-sequence/sdk/package/dist/kit/GameDataHandler.js.map
deleted file mode 100644
index e46a201..0000000
--- a/G102-sequence/sdk/package/dist/kit/GameDataHandler.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameDataHandler.js","sourceRoot":"","sources":["../../src/kit/GameDataHandler.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/api.d.ts b/G102-sequence/sdk/package/dist/kit/api.d.ts
deleted file mode 100644
index dd1fac8..0000000
--- a/G102-sequence/sdk/package/dist/kit/api.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Game API Client Kit
- * Standardized API client for communicating with Game Backend
- */
-export interface GameApiConfig {
- baseUrl: string;
- getHeaders?: () => Record;
-}
-export declare class GameApiClient {
- private config;
- constructor(config: GameApiConfig);
- private request;
- getGameWithProgress(assignmentId: number | string, studentId: string, refresh?: boolean): Promise;
- startLiveSession(assignmentId: number | string, studentId: string, refresh?: boolean): Promise;
- submitAnswer(assignmentId: number | string, studentId: string, questionId: string, answer: any, timeSpent?: number, isTimeout?: boolean): Promise;
- completeSession(assignmentId: number | string, studentId: string): Promise;
- getLeaderboard(assignmentId: number | string, studentId: string): Promise;
-}
-//# sourceMappingURL=api.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/api.d.ts.map b/G102-sequence/sdk/package/dist/kit/api.d.ts.map
deleted file mode 100644
index 41ddb1c..0000000
--- a/G102-sequence/sdk/package/dist/kit/api.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/kit/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,qBAAa,aAAa;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;YAE3B,OAAO;IA6Cf,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,UAAQ;IAIrF,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,UAAQ;IAOlF,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,SAAI,EAAE,SAAS,UAAQ;IAWhI,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;IAOhE,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;CAGxE"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/api.js b/G102-sequence/sdk/package/dist/kit/api.js
deleted file mode 100644
index 61d2822..0000000
--- a/G102-sequence/sdk/package/dist/kit/api.js
+++ /dev/null
@@ -1,86 +0,0 @@
-"use strict";
-/**
- * Game API Client Kit
- * Standardized API client for communicating with Game Backend
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GameApiClient = void 0;
-class GameApiClient {
- constructor(config) {
- this.config = config;
- }
- async request(method, endpoint, body) {
- const url = `${this.config.baseUrl}${endpoint}`;
- const headers = {
- 'Content-Type': 'application/json',
- ...(this.config.getHeaders ? this.config.getHeaders() : {})
- };
- try {
- const res = await fetch(url, {
- method,
- headers,
- body: body ? JSON.stringify(body) : undefined
- });
- if (!res.ok) {
- const errorBody = await res.text();
- let errorMessage = `API Error ${res.status}: ${res.statusText}`;
- let errorCode;
- try {
- const jsonError = JSON.parse(errorBody);
- // Capture error code from response
- if (jsonError.code !== undefined) {
- errorCode = jsonError.code;
- }
- if (jsonError.message)
- errorMessage += ` - ${jsonError.message}`;
- else if (jsonError.error)
- errorMessage += ` - ${jsonError.error}`;
- }
- catch (e) {
- if (errorBody && errorBody.length < 200)
- errorMessage += ` - ${errorBody}`;
- }
- // Throw error object with code and message
- const error = new Error(errorMessage);
- error.code = errorCode;
- error.httpStatus = res.status;
- throw error;
- }
- return await res.json();
- }
- catch (error) {
- console.error('[GameApiClient] Request failed:', error);
- throw error;
- }
- }
- async getGameWithProgress(assignmentId, studentId, refresh = false) {
- return this.request('GET', `/submissions/live/init/${assignmentId}/${studentId}${refresh ? '?refresh=1' : ''}`);
- }
- async startLiveSession(assignmentId, studentId, refresh = false) {
- return this.request('POST', `/submissions/live/start${refresh ? '?refresh=1' : ''}`, {
- assignment_id: assignmentId,
- student_id: studentId
- });
- }
- async submitAnswer(assignmentId, studentId, questionId, answer, timeSpent = 5, isTimeout = false) {
- return this.request('POST', '/submissions/live/answer', {
- assignment_id: assignmentId,
- student_id: studentId,
- question_id: questionId,
- selected_answer: answer,
- time_spent: timeSpent,
- is_timeout: isTimeout
- });
- }
- async completeSession(assignmentId, studentId) {
- return this.request('POST', '/submissions/live/complete', {
- assignment_id: assignmentId,
- student_id: studentId
- });
- }
- async getLeaderboard(assignmentId, studentId) {
- return this.request('GET', `/submissions/leaderboard/${assignmentId}?student_id=${studentId}`);
- }
-}
-exports.GameApiClient = GameApiClient;
-//# sourceMappingURL=api.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/api.js.map b/G102-sequence/sdk/package/dist/kit/api.js.map
deleted file mode 100644
index be111a5..0000000
--- a/G102-sequence/sdk/package/dist/kit/api.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/kit/api.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/index.d.ts b/G102-sequence/sdk/package/dist/kit/index.d.ts
deleted file mode 100644
index a7de88d..0000000
--- a/G102-sequence/sdk/package/dist/kit/index.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './mappers';
-export * from './api';
-export * from './GameDataHandler';
-export * from './react/GamePlayer';
-export * from './react/GameTestPlayer';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/index.d.ts.map b/G102-sequence/sdk/package/dist/kit/index.d.ts.map
deleted file mode 100644
index a5c5956..0000000
--- a/G102-sequence/sdk/package/dist/kit/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kit/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/index.js b/G102-sequence/sdk/package/dist/kit/index.js
deleted file mode 100644
index d64265b..0000000
--- a/G102-sequence/sdk/package/dist/kit/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() { return m[k]; } };
- }
- Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __exportStar = (this && this.__exportStar) || function(m, exports) {
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-__exportStar(require("./mappers"), exports);
-__exportStar(require("./api"), exports);
-__exportStar(require("./GameDataHandler"), exports);
-__exportStar(require("./react/GamePlayer"), exports);
-__exportStar(require("./react/GameTestPlayer"), exports);
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/index.js.map b/G102-sequence/sdk/package/dist/kit/index.js.map
deleted file mode 100644
index 680458a..0000000
--- a/G102-sequence/sdk/package/dist/kit/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/kit/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,wCAAsB;AACtB,oDAAkC;AAClC,qDAAmC;AACnC,yDAAuC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/mappers.d.ts b/G102-sequence/sdk/package/dist/kit/mappers.d.ts
deleted file mode 100644
index ae4f3cd..0000000
--- a/G102-sequence/sdk/package/dist/kit/mappers.d.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Mappers Kit
- * Helper functions to transform data between Client App and Game Iframe
- */
-export interface GamePayloadOptions {
- gameId: string | number;
- userId: string;
- gameData: any;
- answeredQuestions?: any[];
- extraData?: Record;
- endTimeIso?: string;
-}
-export interface IframeGamePayload {
- game_id: string | number;
- user_id: string;
- data: any[];
- completed_question_ids: {
- id: string;
- result: number;
- }[];
- end_time_iso?: string;
- [key: string]: any;
-}
-export declare function prepareCompletedQuestions(answeredQuestions: any[]): {
- id: string;
- result: number;
-}[];
-export declare function createGamePayload(options: GamePayloadOptions): IframeGamePayload;
-export declare function createLeaderboardPayload(apiData: any): any;
-export declare function normalizeAnswerReport(data: any): any;
-//# sourceMappingURL=mappers.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/mappers.d.ts.map b/G102-sequence/sdk/package/dist/kit/mappers.d.ts.map
deleted file mode 100644
index 2068dfc..0000000
--- a/G102-sequence/sdk/package/dist/kit/mappers.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../src/kit/mappers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,sBAAsB,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,wBAAgB,yBAAyB,CAAC,iBAAiB,EAAE,GAAG,EAAE,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAKpG;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CA+BhF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CAsB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAWpD"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/mappers.js b/G102-sequence/sdk/package/dist/kit/mappers.js
deleted file mode 100644
index 5246e57..0000000
--- a/G102-sequence/sdk/package/dist/kit/mappers.js
+++ /dev/null
@@ -1,81 +0,0 @@
-"use strict";
-/**
- * Mappers Kit
- * Helper functions to transform data between Client App and Game Iframe
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.prepareCompletedQuestions = prepareCompletedQuestions;
-exports.createGamePayload = createGamePayload;
-exports.createLeaderboardPayload = createLeaderboardPayload;
-exports.normalizeAnswerReport = normalizeAnswerReport;
-function prepareCompletedQuestions(answeredQuestions) {
- return (answeredQuestions || []).map(a => ({
- id: a.id || a.questionId,
- result: (a.isCorrect || a.result === 1) ? 1 : 0,
- }));
-}
-function createGamePayload(options) {
- const { gameId, userId, gameData, answeredQuestions = [], endTimeIso } = options;
- const completed_question_ids = prepareCompletedQuestions(answeredQuestions);
- // Ưu tiên lấy field .questions hoặc .data, hoặc dùng chính gameData nếu nó là mảng
- let data = [];
- if (Array.isArray(gameData)) {
- data = gameData;
- }
- else if (gameData && Array.isArray(gameData.questions)) {
- data = gameData.questions;
- }
- else if (gameData && Array.isArray(gameData.data)) {
- data = gameData.data;
- }
- const payload = {
- game_id: gameId,
- user_id: userId,
- data: data,
- completed_question_ids: completed_question_ids,
- // Merge các field metadata khác
- ...(typeof gameData === 'object' && !Array.isArray(gameData) ? gameData : {}),
- // Merge extraData
- ...(options.extraData || {})
- };
- // Inject end_time_iso (absolute timestamp for accurate sync)
- if (endTimeIso) {
- payload.end_time_iso = endTimeIso;
- }
- return payload;
-}
-function createLeaderboardPayload(apiData) {
- const topPlayers = apiData.topPlayers || [];
- const userRank = apiData.userRank || null;
- return {
- top_players: topPlayers.map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.user_id,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: userRank ? {
- rank: userRank.rank,
- name: userRank.name || userRank.studentName,
- score: userRank.score ?? userRank.finalScore ?? 0,
- student_id: userRank.studentId || userRank.userId,
- time_spent: userRank.timeSpent ?? userRank.time_spent ?? 0,
- completed_at: userRank.completedAt
- } : null,
- };
-}
-function normalizeAnswerReport(data) {
- // Simplified per user request
- // Input: { question_id: "Q1", result: 1, choice: "2" }
- return {
- question_id: data.question_id || data.questionId || data.id,
- choice: data.choice ?? data.selected_answer ?? data.selectedAnswer,
- result: data.result ?? (data.is_correct ? 1 : 0),
- is_correct: !!(data.result === 1 || data.is_correct === true),
- time_spent: data.time_spent ?? 5,
- is_timeout: !!data.is_timeout
- };
-}
-//# sourceMappingURL=mappers.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/mappers.js.map b/G102-sequence/sdk/package/dist/kit/mappers.js.map
deleted file mode 100644
index 8b4f0c6..0000000
--- a/G102-sequence/sdk/package/dist/kit/mappers.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/kit/mappers.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts b/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts
deleted file mode 100644
index ca1128a..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-import { GameApiConfig } from '../api';
-export interface SessionStatus {
- type: 'new' | 'resumed' | 'timeout' | 'completed' | 'assignment_ended' | 'not_started';
- message: string;
- data?: {
- answered?: number;
- total?: number;
- score?: number;
- remainingTime?: number;
- startedAt?: string;
- };
-}
-export interface GamePlayerError {
- type: 'network' | 'api' | 'timeout' | 'session' | 'not_started' | 'unknown';
- code?: number;
- message: string;
- details?: any;
- canRetry?: boolean;
-}
-export declare const SessionErrorCodes: {
- readonly SESSION_NOT_STARTED: -60;
- readonly SESSION_ENDED: -61;
- readonly SESSION_COMPLETED: -62;
- readonly SESSION_TIMEOUT: -63;
- readonly SESSION_NOT_FOUND: -64;
- readonly SESSION_ALREADY_ANSWERED: -65;
-};
-export interface GamePlayerProps {
- apiConfig: GameApiConfig;
- assignmentId: number;
- studentId: string;
- className?: string;
- style?: React.CSSProperties;
- debug?: boolean;
- onComplete?: (result: any) => void;
- onError?: (error: GamePlayerError) => void;
- onGameLoaded?: (gameInfo: any) => void;
- extraGameData?: Record;
- onLog?: (message: string, type?: 'info' | 'success' | 'error' | 'warning') => void;
- onSessionStatus?: (status: SessionStatus) => void;
- renderLoading?: () => React.ReactNode;
- renderError?: (error: GamePlayerError, retry: () => void) => React.ReactNode;
- loadingTimeout?: number;
-}
-export declare const GamePlayer: React.FC;
-//# sourceMappingURL=GamePlayer.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts.map b/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts.map
deleted file mode 100644
index 28af2a8..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GamePlayer.d.ts","sourceRoot":"","sources":["../../../src/kit/react/GamePlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAiB,aAAa,EAAE,MAAM,QAAQ,CAAC;AAItD,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,kBAAkB,GAAG,aAAa,CAAC;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACL;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAGD,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAEX,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,aAAa,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IACnF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAElD,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8oBhD,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js b/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js
deleted file mode 100644
index afadbd5..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js
+++ /dev/null
@@ -1,583 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GamePlayer = exports.SessionErrorCodes = void 0;
-const jsx_runtime_1 = require("react/jsx-runtime");
-const react_1 = require("react");
-const useGameIframeSDK_1 = require("../../useGameIframeSDK");
-const api_1 = require("../api");
-const mappers_1 = require("../mappers");
-// Session Error Codes (synced with backend)
-exports.SessionErrorCodes = {
- SESSION_NOT_STARTED: -60,
- SESSION_ENDED: -61,
- SESSION_COMPLETED: -62,
- SESSION_TIMEOUT: -63,
- SESSION_NOT_FOUND: -64,
- SESSION_ALREADY_ANSWERED: -65,
-};
-const GamePlayer = ({ apiConfig, assignmentId, studentId, className, style, debug = false, onComplete, onError, onGameLoaded, extraGameData, onLog, onSessionStatus, renderLoading, renderError, loadingTimeout = 30000 }) => {
- const iframeRef = (0, react_1.useRef)(null);
- const [gameUrl, setGameUrl] = (0, react_1.useState)('');
- const [gameState, setGameState] = (0, react_1.useState)(null);
- const [loading, setLoading] = (0, react_1.useState)(true);
- const [error, setError] = (0, react_1.useState)(null);
- const [hasLoadedGame, setHasLoadedGame] = (0, react_1.useState)(false);
- const [apiClient] = (0, react_1.useState)(() => new api_1.GameApiClient(apiConfig));
- // Refs to prevent infinite loops
- const sendLeaderboardRef = (0, react_1.useRef)(null);
- const hasInitRef = (0, react_1.useRef)(false); // Track if init has been called
- const callbacksRef = (0, react_1.useRef)({ onGameLoaded, onLog, onSessionStatus, onError }); // Stable callback refs
- // Update callback refs on each render
- callbacksRef.current = { onGameLoaded, onLog, onSessionStatus, onError };
- // Helper: Create structured error
- const createError = (0, react_1.useCallback)((err) => {
- const errorMsg = err?.message || err?.error || String(err);
- const errorCode = err?.code; // Error code from API response
- // Check error code first (more reliable than message parsing)
- if (errorCode !== undefined) {
- // Session not started
- if (errorCode === exports.SessionErrorCodes.SESSION_NOT_STARTED) {
- return {
- type: 'not_started',
- code: errorCode,
- message: errorMsg || 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- // Session ended
- if (errorCode === exports.SessionErrorCodes.SESSION_ENDED) {
- return {
- type: 'session',
- code: errorCode,
- message: errorMsg || 'Bài tập đã kết thúc',
- details: err,
- canRetry: false
- };
- }
- // Session completed
- if (errorCode === exports.SessionErrorCodes.SESSION_COMPLETED) {
- return {
- type: 'session',
- code: errorCode,
- message: errorMsg || 'Bạn đã hoàn thành bài tập này rồi',
- details: err,
- canRetry: false
- };
- }
- // Session timeout
- if (errorCode === exports.SessionErrorCodes.SESSION_TIMEOUT) {
- return {
- type: 'timeout',
- code: errorCode,
- message: errorMsg || 'Đã hết thời gian làm bài',
- details: err,
- canRetry: false
- };
- }
- }
- // Fallback: Parse error message
- // API errors
- if (errorMsg.includes('API Error') || errorMsg.includes('Failed to fetch')) {
- // Check if it contains session-related message
- if (errorMsg.includes('chưa bắt đầu')) {
- return {
- type: 'not_started',
- message: 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- return {
- type: 'api',
- message: errorMsg,
- details: err,
- canRetry: true
- };
- }
- // Network errors
- if (errorMsg.includes('network') || errorMsg.includes('ECONNREFUSED')) {
- return {
- type: 'network',
- message: 'Lỗi kết nối mạng. Vui lòng kiểm tra internet.',
- details: err,
- canRetry: true
- };
- }
- // Session errors (message-based fallback)
- if (errorMsg.includes('chưa bắt đầu')) {
- return {
- type: 'not_started',
- message: errorMsg || 'Bài tập chưa bắt đầu',
- details: err,
- canRetry: false
- };
- }
- if (errorMsg.includes('hết thời gian') || errorMsg.includes('đã kết thúc') ||
- errorMsg.includes('đã hoàn thành') || errorMsg.includes('session')) {
- return {
- type: 'session',
- message: errorMsg,
- details: err,
- canRetry: false
- };
- }
- // Timeout errors
- if (errorMsg.includes('timeout') || errorMsg.includes('timed out')) {
- return {
- type: 'timeout',
- message: 'Kết nối quá lâu. Vui lòng thử lại.',
- details: err,
- canRetry: true
- };
- }
- return {
- type: 'unknown',
- message: errorMsg || 'Đã xảy ra lỗi không xác định',
- details: err,
- canRetry: true
- };
- }, []);
- // Helper: Handle error with callback
- const handleError = (0, react_1.useCallback)((err) => {
- const gameError = createError(err);
- setError(gameError);
- setLoading(false);
- if (onError) {
- onError(gameError);
- }
- if (onLog) {
- onLog(`[SDK ERR] ${gameError.type}: ${gameError.message}`, 'error');
- }
- }, [createError, onError, onLog]);
- // Retry function
- const retryInit = (0, react_1.useCallback)(() => {
- if (callbacksRef.current.onLog)
- callbacksRef.current.onLog('[SDK] Retrying initialization...', 'info');
- hasInitRef.current = false; // Allow re-init
- setError(null);
- setLoading(true);
- setGameUrl('');
- setGameState(null);
- }, []);
- // Define Handlers
- const handleAnswer = (0, react_1.useCallback)(async (data) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Answer Raw: ${JSON.stringify(data)}`, 'info');
- const report = (0, mappers_1.normalizeAnswerReport)(data);
- if (onLog)
- onLog(`[SDK] Processed Answer: ID ${report.question_id} | Choice: ${report.choice} | ${report.is_correct ? 'Correct' : 'Wrong'}`, 'info');
- if (onLog)
- onLog(`[API REQ] Submitting Answer ID ${report.question_id}...`, 'info');
- const res = await apiClient.submitAnswer(assignmentId, studentId, report.question_id, report.choice, report.time_spent, report.is_timeout);
- if (onLog)
- onLog(`[API RES] Submit Result: ${JSON.stringify(res)}`, 'success');
- }
- catch (err) {
- console.error('[GamePlayer] Submit error:', err);
- if (onLog)
- onLog(`[API ERR] Submit Failed: ${err.message}`, 'error');
- }
- }, [apiClient, assignmentId, studentId, onLog]);
- const handleFinalResult = (0, react_1.useCallback)(async (data) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Final Result Raw: ${JSON.stringify(data)}`, 'info');
- if (onLog)
- onLog('[SDK] Game Complete. Calling API...', 'info');
- const res = await apiClient.completeSession(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Session Completed. Score: ${res.data?.finalScore}`, 'success');
- // Auto-refresh leaderboard after completion to ensure user rank is included
- if (onLog)
- onLog('[SDK] Auto-refreshing leaderboard after completion...', 'info');
- await new Promise(resolve => setTimeout(resolve, 500)); // Small delay for backend to process
- try {
- const lbRes = await apiClient.getLeaderboard(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Post-completion Leaderboard: ${JSON.stringify(lbRes)}`, 'success');
- if (lbRes.success && lbRes.data && sendLeaderboardRef.current) {
- const leaderboardData = {
- top_players: (lbRes.data.topPlayers || []).map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.userId,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: lbRes.data.userRank ? {
- rank: lbRes.data.userRank.rank,
- name: lbRes.data.userRank.name || lbRes.data.userRank.studentName,
- score: lbRes.data.userRank.score ?? lbRes.data.userRank.finalScore ?? 0,
- student_id: lbRes.data.userRank.studentId || lbRes.data.userRank.userId,
- time_spent: lbRes.data.userRank.timeSpent ?? lbRes.data.userRank.time_spent ?? 0,
- completed_at: lbRes.data.userRank.completedAt
- } : null
- };
- if (onLog)
- onLog(`[SDK SEND] Updated Leaderboard: ${JSON.stringify(leaderboardData)}`, 'info');
- sendLeaderboardRef.current(leaderboardData);
- }
- }
- catch (lbErr) {
- if (onLog)
- onLog(`[API ERR] Leaderboard refresh failed: ${lbErr.message}`, 'warning');
- }
- if (onComplete)
- onComplete(res);
- }
- catch (err) {
- console.error('[GamePlayer] Complete error:', err);
- if (onLog)
- onLog(`[API ERR] Complete Failed: ${err.message}`, 'error');
- if (onError)
- onError(err);
- }
- }, [apiClient, assignmentId, studentId, onComplete, onError, onLog]);
- // SDK Hook
- const { isReady, sendGameData, sendLeaderboard } = (0, useGameIframeSDK_1.useGameIframeSDK)({
- iframeRef,
- iframeOrigin: '*',
- debug,
- onGameReady: () => {
- if (onLog)
- onLog('[SDK RECV] Iframe Ready', 'success');
- },
- onAnswerReport: handleAnswer,
- onFinalResult: handleFinalResult,
- onLeaderboardRequest: async (top) => {
- try {
- if (onLog)
- onLog(`[SDK RECV] Leaderboard Request Raw: top=${top}`, 'info');
- if (onLog)
- onLog(`[API REQ] Fetching Leaderboard (top ${top})...`, 'info');
- const res = await apiClient.getLeaderboard(assignmentId, studentId);
- if (onLog)
- onLog(`[API RES] Leaderboard Raw: ${JSON.stringify(res)}`, 'success');
- if (res.success && res.data) {
- const leaderboardData = {
- top_players: (res.data.topPlayers || []).map((p) => ({
- rank: p.rank,
- name: p.name || p.studentName || p.userId,
- score: p.score ?? p.finalScore ?? 0,
- student_id: p.studentId || p.userId,
- time_spent: p.timeSpent ?? p.time_spent ?? 0,
- completed_at: p.completedAt
- })),
- user_rank: res.data.userRank ? {
- rank: res.data.userRank.rank,
- name: res.data.userRank.name || res.data.userRank.studentName,
- score: res.data.userRank.score ?? res.data.userRank.finalScore ?? 0,
- student_id: res.data.userRank.studentId || res.data.userRank.userId,
- time_spent: res.data.userRank.timeSpent ?? res.data.userRank.time_spent ?? 0,
- completed_at: res.data.userRank.completedAt
- } : null
- };
- if (onLog)
- onLog(`[SDK SEND] Leaderboard Payload: ${JSON.stringify(leaderboardData)}`, 'info');
- const sent = sendLeaderboard(leaderboardData);
- if (onLog)
- onLog(sent ? '[SDK] Leaderboard sent successfully' : '[SDK ERR] Failed to send leaderboard', sent ? 'success' : 'error');
- }
- }
- catch (err) {
- console.error('[GamePlayer] Leaderboard error:', err);
- if (onLog)
- onLog(`[API ERR] Leaderboard Failed: ${err.message}`, 'error');
- }
- }
- });
- // Update ref after hook
- sendLeaderboardRef.current = sendLeaderboard;
- // 1. Fetch Game Data & Start Session
- (0, react_1.useEffect)(() => {
- let mounted = true;
- let loadingTimeoutId;
- const initGame = async () => {
- try {
- setLoading(true);
- setError(null);
- if (onLog)
- onLog('[SDK] Initializing Game...', 'info');
- // Set loading timeout
- loadingTimeoutId = setTimeout(() => {
- if (mounted && loading) {
- if (onLog)
- onLog('[SDK WARN] Loading taking longer than expected...', 'warning');
- }
- }, loadingTimeout);
- // getGameWithProgress đã tự động tạo/restore session trong backend
- // thông qua getOrCreateSubmissionCache - không cần gọi startLiveSession riêng
- const res = await apiClient.getGameWithProgress(assignmentId, studentId);
- if (!res.success || !res.data) {
- throw new Error(res.message || 'Failed to load game');
- }
- if (mounted) {
- // Check session status TRƯỚC để quyết định có load game hay không
- const session = res.data.session;
- const progress = res.data.progress;
- // Case 1: Already completed
- if (res.data.isFinished || session?.completed) {
- // CHỈ set error nếu CHƯA load game (lần đầu vào)
- if (!hasLoadedGame) {
- const errorObj = {
- type: 'session',
- message: 'Bạn đã hoàn thành bài tập này rồi',
- details: { score: progress?.score, answered: progress?.answered, total: progress?.total },
- canRetry: false
- };
- setError(errorObj);
- setLoading(false);
- clearTimeout(loadingTimeoutId);
- if (onError)
- onError(errorObj);
- if (onLog)
- onLog(`[SDK] ${errorObj.message}`, 'warning');
- }
- // Luôn gọi callback (cho cả 2 trường hợp)
- if (onSessionStatus) {
- onSessionStatus({
- type: 'completed',
- message: 'Bạn đã hoàn thành bài tập này',
- data: {
- answered: progress?.answered || 0,
- total: progress?.total || 0,
- score: progress?.score || 0
- }
- });
- }
- // Nếu CHƯA load game → STOP
- // Nếu ĐÃ load game → tiếp tục (cho game hiển thị leaderboard)
- if (!hasLoadedGame) {
- return; // ❌ STOP - không load game
- }
- }
- // Case 2: Session timeout
- if (session && session.remainingTime !== null && session.remainingTime <= 0) {
- // CHỈ set error nếu CHƯA load game
- if (!hasLoadedGame) {
- const errorObj = {
- type: 'timeout',
- message: 'Thời gian làm bài đã hết',
- details: { answered: progress?.answered, total: progress?.total },
- canRetry: false
- };
- setError(errorObj);
- setLoading(false);
- clearTimeout(loadingTimeoutId);
- if (onError)
- onError(errorObj);
- if (onLog)
- onLog(`[SDK] ${errorObj.message}`, 'warning');
- }
- // Luôn gọi callback
- if (onSessionStatus) {
- onSessionStatus({
- type: 'timeout',
- message: 'Thời gian làm bài đã hết',
- data: {
- answered: progress?.answered || 0,
- total: progress?.total || 0,
- score: progress?.score || 0,
- remainingTime: 0
- }
- });
- }
- // Nếu CHƯA load game → STOP
- if (!hasLoadedGame) {
- return; // ❌ STOP - không load game
- }
- }
- // Case 3: Valid session - LOAD game
- setGameState(res.data);
- setGameUrl(res.data.gameUrl);
- setLoading(false);
- setHasLoadedGame(true); // ✅ Đánh dấu đã load game
- clearTimeout(loadingTimeoutId);
- if (onGameLoaded)
- onGameLoaded(res.data);
- if (onLog)
- onLog(`[API RES] Game Loaded: ${res.data.title || res.data.gameType || assignmentId}`, 'success');
- // Notify session status for valid sessions
- if (session && onSessionStatus) {
- // Resumed session (có câu đã trả lời)
- if (progress && progress.answered > 0) {
- onSessionStatus({
- type: 'resumed',
- message: `Tiếp tục làm bài (Đã làm ${progress.answered}/${progress.total} câu)`,
- data: {
- answered: progress.answered,
- total: progress.total,
- score: progress.score,
- remainingTime: session.remainingTime,
- startedAt: session.startedAt
- }
- });
- }
- // New session
- else {
- onSessionStatus({
- type: 'new',
- message: 'Bắt đầu làm bài mới',
- data: {
- answered: 0,
- total: progress?.total || 0,
- score: 0,
- remainingTime: session.remainingTime,
- startedAt: session.startedAt
- }
- });
- }
- }
- // Log session info
- if (session && onLog) {
- const sessionInfo = `Session started at ${session.startedAt}, remaining: ${session.remainingTime}s`;
- onLog(`[SDK] ${sessionInfo}`, 'info');
- }
- }
- }
- catch (err) {
- console.error('[GamePlayer] Init error:', err);
- if (mounted) {
- handleError(err);
- }
- }
- };
- if (assignmentId && studentId && !hasInitRef.current) {
- hasInitRef.current = true; // Prevent re-init
- initGame();
- }
- return () => {
- mounted = false;
- hasInitRef.current = false; // ✅ Reset for StrictMode remount
- if (loadingTimeoutId)
- clearTimeout(loadingTimeoutId);
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [assignmentId, studentId]); // ✅ Chỉ re-init khi assignmentId hoặc studentId thay đổi
- // 2. Auto Send Data when Ready
- (0, react_1.useEffect)(() => {
- if (isReady && gameState) {
- // Get expiresAt from session (absolute timestamp for accurate sync)
- const getEndTimeIso = () => {
- const session = gameState.session;
- if (!session)
- return undefined;
- // Ưu tiên dùng expiresAt
- if (session.expiresAt) {
- return session.expiresAt;
- }
- // Fallback: tính từ startedAt + duration
- if (session.startedAt && session.duration) {
- const startTimeMs = new Date(session.startedAt).getTime();
- const expiresAtMs = startTimeMs + (session.duration * 1000);
- return new Date(expiresAtMs).toISOString();
- }
- return undefined;
- };
- const payload = (0, mappers_1.createGamePayload)({
- gameId: gameState.id,
- userId: studentId,
- gameData: gameState.jsonData,
- answeredQuestions: gameState.completed_question_ids,
- extraData: extraGameData,
- endTimeIso: getEndTimeIso() // ✅ Absolute timestamp
- });
- if (onLog)
- onLog(`[SDK SEND] Game Payload: ${JSON.stringify(payload)}`, 'info');
- sendGameData(payload);
- }
- }, [isReady, gameState, studentId, sendGameData, extraGameData, onLog]);
- // ===== RENDER =====
- // 1. Error State
- if (error) {
- if (renderError) {
- return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: renderError(error, retryInit) });
- }
- // Default error UI
- return ((0, jsx_runtime_1.jsxs)("div", { className: "game-player-error", style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- height: '100%',
- padding: '2rem',
- textAlign: 'center',
- backgroundColor: '#f8f9fa',
- ...style
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
- fontSize: '3rem',
- marginBottom: '1rem'
- }, children: error.type === 'network' ? '🌐' :
- error.type === 'timeout' ? '⏱️' :
- error.type === 'session' ? '🔒' :
- error.type === 'not_started' ? '📅' : '⚠️' }), (0, jsx_runtime_1.jsx)("h2", { style: {
- fontSize: '1.5rem',
- fontWeight: 'bold',
- marginBottom: '0.5rem',
- color: error.type === 'not_started' ? '#fd7e14' : '#dc3545'
- }, children: error.type === 'network' ? 'Lỗi Kết Nối' :
- error.type === 'timeout' ? 'Hết Giờ Làm Bài' :
- error.type === 'session' ? 'Phiên Làm Bài Đã Kết Thúc' :
- error.type === 'not_started' ? 'Bài Tập Chưa Bắt Đầu' :
- 'Đã Xảy Ra Lỗi' }), (0, jsx_runtime_1.jsx)("p", { style: {
- fontSize: '1rem',
- color: '#6c757d',
- marginBottom: '1.5rem',
- maxWidth: '500px'
- }, children: error.message }), error.canRetry && ((0, jsx_runtime_1.jsx)("button", { onClick: retryInit, style: {
- padding: '0.75rem 2rem',
- fontSize: '1rem',
- fontWeight: 'bold',
- color: '#fff',
- backgroundColor: '#007bff',
- border: 'none',
- borderRadius: '0.5rem',
- cursor: 'pointer',
- transition: 'background-color 0.2s'
- }, onMouseEnter: (e) => e.currentTarget.style.backgroundColor = '#0056b3', onMouseLeave: (e) => e.currentTarget.style.backgroundColor = '#007bff', children: "\uD83D\uDD04 Th\u1EED L\u1EA1i" })), !error.canRetry && ((0, jsx_runtime_1.jsx)("p", { style: {
- fontSize: '0.875rem',
- color: '#6c757d',
- marginTop: '1rem'
- }, children: "Vui l\u00F2ng li\u00EAn h\u1EC7 gi\u00E1o vi\u00EAn ho\u1EB7c quay l\u1EA1i trang ch\u1EE7" }))] }));
- }
- // 2. Loading State
- if (loading || !gameUrl) {
- if (renderLoading) {
- return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: renderLoading() });
- }
- // Default loading UI
- return ((0, jsx_runtime_1.jsxs)("div", { className: "game-player-loading", style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- height: '100%',
- backgroundColor: '#f8f9fa',
- ...style
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
- width: '50px',
- height: '50px',
- border: '5px solid #e9ecef',
- borderTop: '5px solid #007bff',
- borderRadius: '50%',
- animation: 'spin 1s linear infinite',
- marginBottom: '1rem'
- } }), (0, jsx_runtime_1.jsx)("p", { style: {
- fontSize: '1.125rem',
- color: '#6c757d',
- fontWeight: '500'
- }, children: "\u0110ang t\u1EA3i tr\u00F2 ch\u01A1i..." }), (0, jsx_runtime_1.jsx)("style", { children: `
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- ` })] }));
- }
- // 3. Game Iframe
- return ((0, jsx_runtime_1.jsx)("iframe", { ref: iframeRef, src: gameUrl, className: className, style: { width: '100%', height: '100%', border: 'none', ...style }, allowFullScreen: true }));
-};
-exports.GamePlayer = GamePlayer;
-//# sourceMappingURL=GamePlayer.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js.map b/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js.map
deleted file mode 100644
index 3b94211..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GamePlayer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GamePlayer.js","sourceRoot":"","sources":["../../../src/kit/react/GamePlayer.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts b/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts
deleted file mode 100644
index c056ec8..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-export interface GameTestPlayerProps {
- /**
- * URL của game iframe
- */
- gameUrl: string;
- /**
- * Data game (array of questions)
- */
- gameData: any[];
- /**
- * User ID (optional, default 'test_user')
- */
- userId?: string;
- /**
- * Game ID (optional, default 'test_game')
- */
- gameId?: string | number;
- /**
- * Extra data to pass to iframe
- */
- extraData?: Record;
- /**
- * End time ISO (optional - for countdown)
- */
- endTimeIso?: string;
- /**
- * CSS class
- */
- className?: string;
- /**
- * CSS style
- */
- style?: React.CSSProperties;
- /**
- * Debug mode
- */
- debug?: boolean;
- /**
- * Callback khi nhận answer từ iframe
- */
- onAnswer?: (data: any) => void;
- /**
- * Callback khi game hoàn thành
- */
- onComplete?: (result: any) => void;
- /**
- * Callback log
- */
- onLog?: (message: string, type?: 'info' | 'success' | 'error' | 'warning') => void;
- /**
- * Callback khi iframe yêu cầu leaderboard
- */
- onLeaderboardRequest?: (top: number) => void;
- /**
- * Mock leaderboard data (optional - sẽ tự gửi khi iframe request)
- */
- mockLeaderboard?: {
- top_players: Array<{
- rank: number;
- name: string;
- score: number;
- time_spent?: number;
- }>;
- user_rank?: {
- rank: number;
- name: string;
- score: number;
- time_spent?: number;
- } | null;
- };
-}
-/**
- * GameTestPlayer - Component test đơn giản
- *
- * Chỉ load game data vào iframe, KHÔNG gọi API
- * Dùng để test game iframe locally
- *
- * @example
- * ```tsx
- * console.log(`[${type}] ${msg}`)}
- * onAnswer={(data) => console.log('Answer:', data)}
- * onComplete={(result) => console.log('Complete:', result)}
- * />
- * ```
- */
-export declare const GameTestPlayer: React.FC;
-export default GameTestPlayer;
-//# sourceMappingURL=GameTestPlayer.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts.map b/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts.map
deleted file mode 100644
index 1f40a6b..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameTestPlayer.d.ts","sourceRoot":"","sources":["../../../src/kit/react/GameTestPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,GAAG,EAAE,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEhC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAE5B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAE/B;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IAEnF;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,eAAe,CAAC,EAAE;QACd,WAAW,EAAE,KAAK,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC,CAAC;QACH,SAAS,CAAC,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,CAAC,EAAE,MAAM,CAAC;SACvB,GAAG,IAAI,CAAC;KACZ,CAAC;CACL;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA2HxD,CAAC;AAEF,eAAe,cAAc,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js b/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js
deleted file mode 100644
index 44a2df1..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js
+++ /dev/null
@@ -1,116 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.GameTestPlayer = void 0;
-const jsx_runtime_1 = require("react/jsx-runtime");
-const react_1 = require("react");
-const useGameIframeSDK_1 = require("../../useGameIframeSDK");
-/**
- * GameTestPlayer - Component test đơn giản
- *
- * Chỉ load game data vào iframe, KHÔNG gọi API
- * Dùng để test game iframe locally
- *
- * @example
- * ```tsx
- * console.log(`[${type}] ${msg}`)}
- * onAnswer={(data) => console.log('Answer:', data)}
- * onComplete={(result) => console.log('Complete:', result)}
- * />
- * ```
- */
-const GameTestPlayer = ({ gameUrl, gameData, userId = 'test_user', gameId = 'test_game', extraData, endTimeIso, className, style, debug = false, onAnswer, onComplete, onLog, onLeaderboardRequest, mockLeaderboard }) => {
- const iframeRef = (0, react_1.useRef)(null);
- const [isLoading, setIsLoading] = (0, react_1.useState)(true);
- // SDK Hook
- const { isReady, sendGameData, sendLeaderboard } = (0, useGameIframeSDK_1.useGameIframeSDK)({
- iframeRef,
- iframeOrigin: '*',
- debug,
- onGameReady: () => {
- if (onLog)
- onLog('[TEST] Iframe Ready', 'success');
- setIsLoading(false);
- },
- onAnswerReport: (data) => {
- if (onLog)
- onLog(`[TEST] Answer: ${JSON.stringify(data)}`, 'info');
- if (onAnswer)
- onAnswer(data);
- },
- onFinalResult: (result) => {
- if (onLog)
- onLog(`[TEST] Complete: ${JSON.stringify(result)}`, 'success');
- if (onComplete)
- onComplete(result);
- },
- onLeaderboardRequest: (top) => {
- if (onLog)
- onLog(`[TEST] Leaderboard Request: top=${top}`, 'info');
- if (onLeaderboardRequest)
- onLeaderboardRequest(top);
- // Auto send mock leaderboard if provided
- if (mockLeaderboard) {
- if (onLog)
- onLog(`[TEST] Sending mock leaderboard`, 'info');
- sendLeaderboard(mockLeaderboard);
- }
- }
- });
- // Auto send game data when ready
- (0, react_1.useEffect)(() => {
- if (isReady && gameData) {
- const payload = {
- game_id: String(gameId),
- user_id: userId,
- data: gameData,
- completed_question_ids: [],
- ...(extraData || {})
- };
- if (endTimeIso) {
- payload.end_time_iso = endTimeIso;
- }
- if (onLog)
- onLog(`[TEST] Sending Game Data: ${gameData.length} items`, 'info');
- sendGameData(payload);
- }
- }, [isReady, gameData, gameId, userId, extraData, endTimeIso, sendGameData, onLog]);
- return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', width: '100%', height: '100%', ...style }, children: [isLoading && ((0, jsx_runtime_1.jsx)("div", { style: {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- backgroundColor: 'rgba(255,255,255,0.9)',
- zIndex: 10
- }, children: (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
- width: '40px',
- height: '40px',
- border: '4px solid #e9ecef',
- borderTop: '4px solid #007bff',
- borderRadius: '50%',
- animation: 'spin 1s linear infinite',
- margin: '0 auto 1rem'
- } }), (0, jsx_runtime_1.jsx)("p", { style: { color: '#6c757d' }, children: "Loading game..." }), (0, jsx_runtime_1.jsx)("style", { children: `
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- ` })] }) })), (0, jsx_runtime_1.jsx)("iframe", { ref: iframeRef, src: gameUrl, className: className, style: {
- width: '100%',
- height: '100%',
- border: 'none'
- }, allowFullScreen: true })] }));
-};
-exports.GameTestPlayer = GameTestPlayer;
-exports.default = exports.GameTestPlayer;
-//# sourceMappingURL=GameTestPlayer.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js.map b/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js.map
deleted file mode 100644
index 147797c..0000000
--- a/G102-sequence/sdk/package/dist/kit/react/GameTestPlayer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"GameTestPlayer.js","sourceRoot":"","sources":["../../../src/kit/react/GameTestPlayer.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts b/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts
deleted file mode 100644
index e670292..0000000
--- a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * SenaGame SDK Loader
- *
- * Ready-to-use interface for game developers.
- * Handles SDK iframe creation, communication, and lifecycle.
- *
- * Usage:
- * ```html
- *
- *
- * ```
- *
- * @version 1.0.0
- */
-export interface SenaGameConfig {
- /** Path to SDK iframe HTML file (can be versioned) */
- iframePath: string;
- /** Game mode: 'live' | 'preview' */
- mode: 'live' | 'preview';
- /** Game code for identification */
- gameCode: string;
- /** Enable debug logging */
- debug?: boolean;
- /** Timeout for SDK initialization (ms) */
- timeout?: number;
- /** Custom iframe style */
- iframeStyle?: string;
- onReady?: (sdk: SenaGameSDK) => void;
- onDataReady?: (payload: DataReadyPayload) => void;
- onAnswerResult?: (result: AnswerResultPayload) => void;
- onGameComplete?: (result: GameCompletePayload) => void;
- onSessionStart?: (session: SessionStartPayload) => void;
- onError?: (error: Error) => void;
-}
-export interface GameItem {
- id: string;
- question: string;
- options?: string[];
- answer?: string | number;
- [key: string]: any;
-}
-export interface GameData {
- items: GameItem[];
- [key: string]: any;
-}
-export interface AnswerPayload {
- questionId: string;
- selectedAnswer: string | number | string[];
- timeSpent?: number;
-}
-export interface DataReadyPayload {
- items: GameItem[];
- totalQuestions: number;
- completedCount: number;
- resumeData?: Array<{
- id: string;
- result: 0 | 1;
- }>;
-}
-export interface AnswerResultPayload {
- questionId: string;
- isCorrect: boolean;
- correctAnswer: string | number;
- score: number;
- currentScore: number;
- totalAnswered: number;
-}
-export interface GameCompletePayload {
- success: boolean;
- finalScore: number;
- correctCount: number;
- totalQuestions: number;
- wrongCount: number;
- total: number;
-}
-export interface SessionStartPayload {
- assignmentId: number;
- userId: string;
- gameId: string;
- startedAt: string;
-}
-export declare class SenaGameSDK {
- private config;
- private iframe;
- private isReady;
- private isDataReady;
- private pendingMessages;
- private initPromise;
- private initResolver;
- private timeoutId;
- /** SDK version */
- static readonly VERSION = "1.0.0";
- constructor(config: SenaGameConfig);
- /**
- * Push game data to SDK
- */
- pushData(data: any): void;
- /**
- * Submit an answer
- */
- submitAnswer(answer: AnswerPayload): void;
- /**
- * Complete the game
- */
- completeGame(): void;
- /**
- * Get current status
- */
- getStatus(): void;
- /**
- * Wait for SDK to be ready
- */
- ready(): Promise;
- /**
- * Check if SDK is ready
- */
- get sdkReady(): boolean;
- /**
- * Check if data is ready
- */
- get dataReady(): boolean;
- /**
- * Destroy the SDK instance
- */
- destroy(): void;
- private _init;
- private _createIframe;
- private _send;
- private _handleMessage;
- private _onSDKReady;
- private _onDataReady;
- private _onAnswerResult;
- private _onGameComplete;
- private _onSessionStart;
- private _error;
- private _log;
-}
-export default SenaGameSDK;
-//# sourceMappingURL=SenaGameSDK.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts.map b/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts.map
deleted file mode 100644
index 4a7bc6e..0000000
--- a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SenaGameSDK.d.ts","sourceRoot":"","sources":["../../src/loader/SenaGameSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js b/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js
deleted file mode 100644
index 30bacc6..0000000
--- a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js
+++ /dev/null
@@ -1,361 +0,0 @@
-"use strict";
-/**
- * SenaGame SDK Loader
- *
- * Ready-to-use interface for game developers.
- * Handles SDK iframe creation, communication, and lifecycle.
- *
- * Usage:
- * ```html
- *
- *
- * ```
- *
- * @version 1.0.0
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.SenaGameSDK = void 0;
-// ========================================
-// MESSAGE TYPES (matching SDK)
-// ========================================
-const MSG = {
- // Outgoing (Game → SDK)
- INIT: 'SDK_INIT',
- PUSH_DATA: 'SDK_PUSH_DATA',
- SUBMIT_ANSWER: 'SDK_CHECK_ANSWER',
- COMPLETE_GAME: 'SDK_COMPLETE_GAME',
- GET_STATUS: 'SDK_GET_STATUS',
- // Incoming (SDK → Game)
- READY: 'SDK_READY',
- DATA_READY: 'SDK_DATA_READY',
- ANSWER_RESULT: 'SDK_ANSWER_RESULT',
- GAME_COMPLETE: 'SDK_GAME_COMPLETE',
- SESSION_STARTED: 'SDK_SESSION_STARTED',
- STATUS: 'SDK_STATUS',
- ERROR: 'SDK_ERROR',
-};
-// ========================================
-// DEFAULT CONFIG
-// ========================================
-const DEFAULT_CONFIG = {
- iframePath: '../sdk-iframe/index.html',
- mode: 'preview',
- gameCode: '',
- debug: false,
- timeout: 10000,
- iframeStyle: 'position:fixed;width:1px;height:1px;left:-9999px;border:none;',
-};
-// ========================================
-// SENA GAME SDK CLASS
-// ========================================
-class SenaGameSDK {
- constructor(config) {
- this.iframe = null;
- this.isReady = false;
- this.isDataReady = false;
- this.pendingMessages = [];
- this.initResolver = null;
- this.timeoutId = null;
- this.config = { ...DEFAULT_CONFIG, ...config };
- // --- CLEANUP OLD LISTENERS ---
- // Tránh trường hợp init SDK nhiều lần bị trùng listener cũ
- const oldSDK = window._sena_game_sdk_instance;
- if (oldSDK && typeof oldSDK.destroy === 'function') {
- oldSDK.destroy();
- }
- window._sena_game_sdk_instance = this;
- // Create promise for ready state
- this.initPromise = new Promise((resolve, reject) => {
- this.initResolver = { resolve, reject };
- });
- // Bind methods
- this._handleMessage = this._handleMessage.bind(this);
- // Auto-initialize
- this._init();
- }
- // ----------------------------------------
- // PUBLIC API
- // ----------------------------------------
- /**
- * Push game data to SDK
- */
- pushData(data) {
- // Safe extraction of the array
- let itemsArray = [];
- if (Array.isArray(data)) {
- itemsArray = data;
- }
- else if (data && Array.isArray(data.items)) {
- itemsArray = data.items;
- }
- else if (data && Array.isArray(data.data)) {
- itemsArray = data.data;
- }
- else if (data && data.items && typeof data.items === 'object') {
- itemsArray = [data.items];
- }
- else if (data && data.data && typeof data.data === 'object') {
- itemsArray = [data.data];
- }
- // Transform to SDK iframe internal format
- const payload = {
- data: itemsArray,
- completed_question_ids: (data && data.completed_question_ids) || []
- };
- this._send(MSG.PUSH_DATA, payload);
- }
- /**
- * Submit an answer
- */
- submitAnswer(answer) {
- // Transform to SDK iframe format
- const payload = {
- question_id: answer.questionId,
- choice: answer.selectedAnswer,
- time_spent: answer.timeSpent ?? 0
- };
- this._send(MSG.SUBMIT_ANSWER, payload);
- }
- /**
- * Complete the game
- */
- completeGame() {
- this._send(MSG.COMPLETE_GAME, {});
- }
- /**
- * Get current status
- */
- getStatus() {
- this._send(MSG.GET_STATUS, {});
- }
- /**
- * Wait for SDK to be ready
- */
- async ready() {
- if (this.isReady)
- return this;
- return this.initPromise;
- }
- /**
- * Check if SDK is ready
- */
- get sdkReady() {
- return this.isReady;
- }
- /**
- * Check if data is ready
- */
- get dataReady() {
- return this.isDataReady;
- }
- /**
- * Destroy the SDK instance
- */
- destroy() {
- window.removeEventListener('message', this._handleMessage);
- if (this.timeoutId) {
- clearTimeout(this.timeoutId);
- }
- if (this.iframe && this.iframe.parentNode) {
- this.iframe.parentNode.removeChild(this.iframe);
- }
- window.removeEventListener('message', this._handleMessage);
- this.isReady = false;
- this._log('SDK destroyed');
- }
- // ----------------------------------------
- // PRIVATE METHODS
- // ----------------------------------------
- _init() {
- this._log('Initializing SenaGameSDK...');
- // Setup message listener
- window.addEventListener('message', this._handleMessage);
- // Create iframe
- this._createIframe();
- // Setup timeout
- this.timeoutId = setTimeout(() => {
- if (!this.isReady) {
- const error = new Error('SDK initialization timeout');
- this._error(error);
- if (this.initResolver) {
- this.initResolver.reject(error);
- }
- }
- }, this.config.timeout);
- }
- _createIframe() {
- this.iframe = document.createElement('iframe');
- this.iframe.id = 'sena-game-sdk-iframe';
- this.iframe.src = this.config.iframePath;
- this.iframe.style.cssText = this.config.iframeStyle || '';
- this.iframe.onload = () => {
- this._log('Iframe loaded, sending INIT...');
- setTimeout(() => {
- this._send(MSG.INIT, {
- mode: this.config.mode,
- game_code: this.config.gameCode,
- });
- }, 100);
- };
- this.iframe.onerror = () => {
- this._error(new Error('Failed to load SDK iframe'));
- };
- document.body.appendChild(this.iframe);
- this._log(`Iframe created: ${this.config.iframePath}`);
- }
- _send(type, payload) {
- if (!this.iframe || !this.iframe.contentWindow) {
- this._log(`Queuing message: ${type}`, 'warn');
- this.pendingMessages.push({ type, payload });
- return;
- }
- const message = { type, payload, timestamp: Date.now() };
- this._log(`→ ${type}`, 'send');
- this.iframe.contentWindow.postMessage(message, '*');
- }
- _handleMessage(event) {
- const data = event.data;
- if (!data || !data.type)
- return;
- // Only process SDK messages
- if (!data.type.startsWith('SDK_'))
- return;
- this._log(`← ${data.type}`, 'recv');
- switch (data.type) {
- case MSG.READY:
- this._onSDKReady();
- break;
- case MSG.DATA_READY:
- this._onDataReady(data.payload);
- break;
- case MSG.ANSWER_RESULT:
- this._onAnswerResult(data.payload);
- break;
- case MSG.GAME_COMPLETE:
- this._onGameComplete(data.payload);
- break;
- case MSG.SESSION_STARTED:
- this._onSessionStart(data.payload);
- break;
- case MSG.ERROR:
- this._error(new Error(data.payload?.message || 'SDK Error'));
- break;
- }
- }
- _onSDKReady() {
- this.isReady = true;
- if (this.timeoutId) {
- clearTimeout(this.timeoutId);
- this.timeoutId = null;
- }
- // Flush pending messages
- while (this.pendingMessages.length > 0) {
- const msg = this.pendingMessages.shift();
- if (msg) {
- this._send(msg.type, msg.payload);
- }
- }
- // Callback
- if (this.config.onReady) {
- this.config.onReady(this);
- }
- // Resolve promise
- if (this.initResolver) {
- this.initResolver.resolve(this);
- }
- this._log('✅ SDK Ready!');
- }
- _onDataReady(payload) {
- this.isDataReady = true;
- // Normalize payload to camelCase
- const normalized = {
- items: payload.items || [],
- totalQuestions: payload.total_questions || payload.totalQuestions || 0,
- completedCount: payload.completed_count || payload.completedCount || 0,
- resumeData: payload.resume_data || payload.resumeData || []
- };
- if (this.config.onDataReady) {
- this.config.onDataReady(normalized);
- }
- this._log(`✅ Data Ready: ${normalized.items.length} items`);
- }
- _onAnswerResult(payload) {
- const normalized = {
- questionId: payload.question_id || payload.questionId,
- isCorrect: payload.correct !== undefined ? payload.correct : payload.isCorrect,
- correctAnswer: payload.correct_answer || payload.correctAnswer || '',
- score: payload.score || 0,
- currentScore: payload.current_score || payload.currentScore || 0,
- totalAnswered: payload.total_answered || payload.totalAnswered || 0
- };
- if (this.config.onAnswerResult) {
- this.config.onAnswerResult(normalized);
- }
- }
- _onGameComplete(payload) {
- const normalized = {
- success: payload.success !== undefined ? payload.success : true,
- finalScore: payload.score !== undefined ? payload.score : (payload.finalScore || 0),
- correctCount: payload.correct !== undefined ? payload.correct : (payload.correctCount || 0),
- totalQuestions: payload.total !== undefined ? payload.total : (payload.totalQuestions || 0),
- wrongCount: payload.wrong !== undefined ? payload.wrong : (payload.wrongCount || 0),
- total: payload.total || 0
- };
- if (this.config.onGameComplete) {
- this.config.onGameComplete(normalized);
- }
- }
- _onSessionStart(payload) {
- const normalized = {
- assignmentId: payload.assignment_id || payload.assignmentId,
- userId: payload.student_id || payload.userId,
- gameId: payload.game_code || payload.gameId,
- startedAt: payload.started_at || payload.startedAt || new Date().toISOString()
- };
- if (this.config.onSessionStart) {
- this.config.onSessionStart(normalized);
- }
- }
- _error(error) {
- this._log(`❌ Error: ${error.message}`, 'error');
- if (this.config.onError) {
- this.config.onError(error);
- }
- }
- _log(message, type = 'info') {
- if (!this.config.debug)
- return;
- const prefix = '[SenaGameSDK]';
- const styles = {
- info: 'color: #888',
- send: 'color: #ff0',
- recv: 'color: #0f0',
- warn: 'color: #fa0',
- error: 'color: #f00',
- };
- console.log(`%c${prefix} ${message}`, styles[type] || styles.info);
- }
-}
-exports.SenaGameSDK = SenaGameSDK;
-/** SDK version */
-SenaGameSDK.VERSION = '1.0.0';
-// ========================================
-// EXPORT FOR BROWSER (UMD)
-// ========================================
-if (typeof window !== 'undefined') {
- window.SenaGameSDK = SenaGameSDK;
-}
-exports.default = SenaGameSDK;
-//# sourceMappingURL=SenaGameSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js.map b/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js.map
deleted file mode 100644
index d85a575..0000000
--- a/G102-sequence/sdk/package/dist/loader/SenaGameSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SenaGameSDK.js","sourceRoot":"","sources":["../../src/loader/SenaGameSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/index.d.ts b/G102-sequence/sdk/package/dist/loader/index.d.ts
deleted file mode 100644
index 1588cde..0000000
--- a/G102-sequence/sdk/package/dist/loader/index.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * SenaGame SDK Loader
- * Export all types and classes for game developers
- */
-export { SenaGameSDK, type SenaGameConfig, type GameItem, type GameData, type AnswerPayload, type DataReadyPayload, type AnswerResultPayload, type GameCompletePayload, type SessionStartPayload, } from './SenaGameSDK';
-export { SenaGameSDK as default } from './SenaGameSDK';
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/index.d.ts.map b/G102-sequence/sdk/package/dist/loader/index.d.ts.map
deleted file mode 100644
index d00f0a2..0000000
--- a/G102-sequence/sdk/package/dist/loader/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GAC3B,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/index.js b/G102-sequence/sdk/package/dist/loader/index.js
deleted file mode 100644
index 120bc19..0000000
--- a/G102-sequence/sdk/package/dist/loader/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-"use strict";
-/**
- * SenaGame SDK Loader
- * Export all types and classes for game developers
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.default = exports.SenaGameSDK = void 0;
-var SenaGameSDK_1 = require("./SenaGameSDK");
-Object.defineProperty(exports, "SenaGameSDK", { enumerable: true, get: function () { return SenaGameSDK_1.SenaGameSDK; } });
-var SenaGameSDK_2 = require("./SenaGameSDK");
-Object.defineProperty(exports, "default", { enumerable: true, get: function () { return SenaGameSDK_2.SenaGameSDK; } });
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/loader/index.js.map b/G102-sequence/sdk/package/dist/loader/index.js.map
deleted file mode 100644
index 748d951..0000000
--- a/G102-sequence/sdk/package/dist/loader/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAUuB;AATnB,0GAAA,WAAW,OAAA;AAWf,6CAAuD;AAA9C,sGAAA,WAAW,OAAW"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts b/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts
deleted file mode 100644
index 2f6b05f..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * SDK Iframe Core
- * Chạy trong hidden iframe riêng biệt
- *
- * Responsibilities:
- * - Receive data từ parent (preview mode)
- * - Fetch data từ API (live mode)
- * - Store answers securely
- * - Verify answers locally (fast feedback)
- * - Sync với server (background)
- * - Report results
- */
-interface SdkIframeConfig {
- debug?: boolean;
- allowedOrigins?: string[];
-}
-export declare class SdkIframeCore {
- private config;
- private boundMessageHandler;
- private mode;
- private gameCode;
- private assignmentId;
- private studentId;
- private apiBaseUrl;
- private authToken;
- private originalItems;
- private clientItems;
- private sanitizedItems;
- private userAnswers;
- private completedQuestions;
- private isInitialized;
- private parentOrigin;
- constructor(config?: SdkIframeConfig);
- private setupMessageListener;
- private handleMessage;
- private isAllowedOrigin;
- private handleInit;
- private handlePushData;
- private handleCheckAnswer;
- /**
- * Submit answer to server and wait for result (Live mode)
- */
- private submitAnswerToServer;
- private handleGetResult;
- private handleRetrySync;
- private processData;
- private fetchLiveData;
- private sendToParent;
- private sendError;
- private log;
- destroy(): void;
-}
-declare global {
- interface Window {
- SdkIframe: SdkIframeCore;
- }
-}
-export {};
-//# sourceMappingURL=SdkIframeCore.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts.map b/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts.map
deleted file mode 100644
index 87301e1..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/SdkIframeCore.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SdkIframeCore.d.ts","sourceRoot":"","sources":["../../src/sdk-iframe/SdkIframeCore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoCH,UAAU,eAAe;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAMD,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,mBAAmB,CAAgD;IAC3E,OAAO,CAAC,IAAI,CAA2C;IACvD,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,SAAS,CAAc;IAG/B,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,kBAAkB,CAA0B;IAEpD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,MAAM,GAAE,eAAoB;IAcxC,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;IA6CrB,OAAO,CAAC,eAAe;YAWT,UAAU;IA0CxB,OAAO,CAAC,cAAc;YAkBR,iBAAiB;IA8H/B;;OAEG;YACW,oBAAoB;IA2ClC,OAAO,CAAC,eAAe;YAuBT,eAAe;IA6C7B,OAAO,CAAC,WAAW;YAuCL,aAAa;IAyC3B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,GAAG;IAsBX,OAAO,IAAI,IAAI;CASlB;AAMD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,SAAS,EAAE,aAAa,CAAC;KAC5B;CACJ"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts b/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts
deleted file mode 100644
index 9e0dfeb..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * SDK Iframe exports
- */
-import { SdkIframeCore } from './SdkIframeCore';
-export * from './types';
-export { SdkIframeCore };
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts.map b/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts.map
deleted file mode 100644
index a5f13cd..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk-iframe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/index.html b/G102-sequence/sdk/package/dist/sdk-iframe/index.html
deleted file mode 100644
index 4fe3dc9..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Sena SDK Iframe
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/sdk-e4180185b9b6b9a02ad3.js b/G102-sequence/sdk/package/dist/sdk-iframe/sdk-e4180185b9b6b9a02ad3.js
deleted file mode 100644
index b427157..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/sdk-e4180185b9b6b9a02ad3.js
+++ /dev/null
@@ -1 +0,0 @@
-function a0_0x13ba(){const _0x233fe8=['AvHVAgu','AxnOlG','uNbjCgu','tCoOBW','Aw1Hz2vFDxjS','zgj3Ewu','u2HLigDVzxmGDa','Eff6qMm','u0rlx1nztKnFrq','Bg9xs0q','smoGie7HU5LP','wNncqM8','qu5tv0vsx05pva','AgfUzgXLuhvZAa','Dhrmq1G','mtmWodi3ow9ZAwfRrW','yxD5C1q','y2f0zwDVCNK','D2nxAMq','Dgv4Da','rxHctwi','yMv3rxm','AgfZ','B3jL','zYbYyxCGzgf0yq','D3vSrve','EMHRAuK','tfrWy2q','vMTLrwy','u3b3swC','qMfUyw5H','EerQyum','tNfJtem','vK9ey2m','ENj1u0e','BI9QC29U','tM1swKW','yxvKAw9FDxjS','swzNqK0','s1Hwsvq','rg9N','twLZC2LUzYbHCa','wNr6EMS','Bgvhyw1Lq29Kzq','tvjQsMm','x19JCMvHDgvcAq','Ag9fA08','BgPTvxe','x19ZAhvMzMXLza','rZaWnq','r3bwAwe','q3nYyMW','ChjLDMLLDYbTBW','zvPYr1u','BmoGigFdRd8','EKDyzgi','rufewq','BNrjza','v0vxAuq','BgXVD2vKigLUia','id0G','tu9ds19hmteW','BwfW','sLr2qKi','wMXryK4','DML1Awm','B295ENC','su5jvf9fuLjpuG','yunfBMG','igFdRd8','u0rlx0Losvq','DwvZDgLVBNm','z0P6BNG','BMf1vuC','zgf0yq','zxn0Aw9Uig9WDa','EKj5t3G','rw5NBgLZAc4','Aw9U','BfHZA0q','tu9ds19hmtiX','sgvtC3G','uMv0CNKGzMfPBa','u0rlx01fu1nbrW','u2vXDwvUy2uGuW','BwXUq3u','DeTZrNG','BZmUBxaZ','4P2mifDYB25NlIbz','uwPdzgq','EgvNr0C','B3jPz2LU','sNzAEwy','zLbjCLy','D1fItLO','quHOsMy','BwLZC2LUz19Szq','vgHL','DNzsAu4','suvlDeW','zgznANK','uwnQDhu','z2v0','AgfUzgXLr2v0uG','tMviwwO','rw5vvvC','Aw1Hz2u','y2XLyxi','q29UihBHUQ10ig7dOa','rZeYmq','D2fYBG','q3n4C08','z2fTzunVzgu','C3rLBMvY','u2vUDdOG','u0rlx0vsuK9s','C3rYAw5NAwz5','yw5ZD2vY','s1vbtMG','vuzKuLu','vvPvzMS','AgfUzgXLtwvZCW','zw1Z','B29byNe','Axn6vLy','DvnszMy','vuXqB1O','Aw92vhy','uKXuyNK','wgjYCwK','vw5RBM93BIbNyq','mti2nJeZognjBMv0yq','u0v2wgG','l3n1yM1PC3nPBW','tNfTu0u','D3H4sfK','w0rLDL0Gtg9Hza','rZeYmG','qvfwu3i','wwDZquS','tLzkBg0','C3rHDhvZ','DhrLCL9JB3vUDa','y3jLyxrL','rgXyC2K','ig5VDcbMB3vUza','EunIBKi','DwrPBY0Y','CM91BMq','zeH2Cve','yxnXzvK','C2vXDwvUy2vFCW','yw5KBgvYxsbvBG','rgf0ysbWCM9Jzq','yMLUza','ignVBxbSzxrLza','uxvLC3rPB24G','ihbSyxLZigzVBW','Bgf6Eq','BK5UA3i','rfjbs3y','qLrqEM0','qMncuhu','zxj0Eq','Cg9ZDe1LC3nHzW','yMn4EgC','u0rlx0nirunlxW','z2fTzv9JB2rL','sw5PDgLHBgL6zq','suvhuMO','ic0+ici','yLb4DM4','u0rlufu','twHfAhG','t0rpAg4','y2f0y2G','D2fQvwO','zxn1Bhq','z2viyw5KBgvY','A3zLCee','D3bLD20','rgf0yq','ELPJEhi','DerwyK8','ALfKwgG','zgvMyxvSDa','D1L3Aey','wM5mwK4','yw1WBguUy29TlW','igrLC3rYB3LLza','tvvguwG','rMfPBgvKihrVia','tK9ux0Losvrjqq','u0rlx1bvu0HFra','C3DLCIbJAgvJAW','W6jTimsrW7PUzYbJ4BUN','vgLtrMy','zxjYB3i','u0rlx0zjtKfmxW','rZeYma','zNjVBq','C3CX','u0rlx1jfvfjzxW','zKHlCfm','zNn4BfC','rKrsy0S','tezxBLq','zw5JzteUBxaZ','Ew1lAuK','ANvTChm','rfbfBuW','Cwn5s3K','ihvUyxv0Ag9YAq','C3vIBwL0qw5ZDW','B25usLi','z3bmzhC','D05YrLe','sLfeq1m','t3jfzLi','AxnFDgLTzw91Da','C3HUwfa','ywrK','qMLYza','ww5PAMq','yNDmBe0','ruXfueHbtLq','tu9ds19hmteX','Dw5RBM93BG','yxvKAw8Vy29TCa','ChjLDMLLDW','Ce5ABw4','zM9VDgjHBgW','rMLZAa','Cenkrvi','yM91BMrnzxnZyq','A25VD24Gz2fTzq','uNfTBMy','C3bSAwnL','qMnlufe','qMvHCMvYia','ELHUC2q','tMLquNu','uKfxENy','XjddONKGBmoGihf14BQJ','Bfbqs0m','EMPJtNG','CgfYzw50t3jPzW','sg1OuK0','wfDTsu8','BwL0igfUC3DLCG','C2L6zq','uMPOEhm','zM94','vejVwKO','qKfhEgi','B3jK','mvDID3rqsq','CIbHC3nPz25Tzq','AKjoDgi','vgJHU6CGXjhdTcbJ4BUNyq','rhjgz3q','tu9ds19hmtiY','yKfnq3G','BMrPBMC','rv9uwvbfuW','su5jvcbMAxjZDa','uLvYwuK','zc5QCgC','tu9ds19hmda0','yxvKAw8VyMfUyq','wNH5qxO','zxnZywDL','rxPPCei','mtG5ntiYodfNEfPAAfq','y3PVEeG','AxnjBML0AwfSAq','Bg9JyxrPB24','Cgf5Bg9Hza','tgPKyvC','x2LK','uunIzhG','ihnSzwvWAw5NlG','vLLfv2i','ifzP4BUhDcboyw0G','Dgv4Dc1PBwfNzq','vKzrA2K','qwXqtxK','D2vYihzLCMLMAq','zMv0y2HmAxzLra','s2D5Cge','CxvLC3rPB24','q2JHU41UigJdRg5Oia','CKDfyMm','CML0y1O','C2vUzfrVugfYzq','qw5ZD2vYigzVCG','EK16y1K','vgzrB2m','ChjVy2vZC0rHDa','CxvPEG','rZeXmW','q2JHU41UihbOW6f0ia','zxbqBvy','C3rYAw5N','CxvPy2S','BwnwBum','zgv4EuC','tenqwhO','vKvWvxC','y29TCgXLDgvKxW','BMLWtMy','yw5ZD2vYx3zHBa','vxvTyuW','u0LlAvC','tu9ds19hmdaZ','BZeUBxaZ','q0npzxi','yxbWBgLJyxrPBW','sw52ywXPzcbXDq','qLrHDeC','CwHqveS','C3LUy2vK','Exn0D24','DK9Wvg4','ywHgyNG','odG4ndm1uLLLrM9V','tu9ds19hmteZ','Dgv4Dc1HDwrPBW','rKvuq0HFrvjstW','yw1K','BKPevee','t3bfuLi','D2nTBxC','AfjJq2C','tfncBeW','x1jfu1vmva','z0fvyuq','uhHWz2y','v1nbEKu','y29Kzq','EvLJsxG','mZGYmdKYmfjXzMDTEG','CxvLC3rPB25Z','rvn3sLm','rvrgDfK','EvPivu0','BfvRBvO','vvHeBNm','ntuXntK5nuHvugnLva','ze14DwG','yxvKAw8','C2nVCMu','y05lC3i','wu5jqNC','tKj0yxK','yxrH','tu9ds19hmda1','qMv5vxm','DYbJAg9Py2u','uwzoAu4','yxvKAw8VCxvLCW','veTos0q','zgv2','tfjKA0G','qxv0Ag9YAxPHDa','ufDUuNO','r2fTzvnesW','v2XMs1y','zM9YrwfJAa','A3HzCeG','XjddOcbo4BQ1BMC','z2LUCW','CMfUzg9T','B3iG','l2DHBwvZlW','A2v5CW','rxn0AgK','D2PTzg8','CwPszhq','CNrhtg8','q1jxteC','v1bks0q','C3DLCG','u2rRswzYyw1LqW','EeLSCNy','wKrkvKS','DxnLCKfUC3DLCG','AhLHDwG','sw1Hz2u','y2HVAwnL','zgvMAw5LuhjVCa','rxjYB3i6ia','ktOG','Bfblvvu','uxvPEIbuzxH0lq','u2vYDMvYigvYCG','u1LoqW','sMLOtwO','tw9JA0rHDge','igfUC3DLCIbKzq','zxzLCNK','rZaWmG','nKjSuw5SEq','u0rlx1nztKnFuW','BwLU','A2fezhK','B3jPz2LUywXjDa','u0rlx0rbvefFuG','r3DTsem','CKnSAwvUDa','D2vY','BgvKihrVihn1yG','t1DICuK','s0T0vxK','zMv0y2GGBgL2zq','z2v0tw9JA0rHDa','sNL1teO','z1jxwLe','zxHWB3j0CW','BKPIuLO','Ahr0Chm6lY9LEa','CfP6s2u','DxjIzfG','ywrACeC','qvbjievYCM9YoG','t2TcEeC','zxjuB1nLCNzLCG','rZeXma','AxntzgTnzxnZyq','wwziweO','Aw5MBW','CMvTB3zLrxzLBG','ssbSB3zLigXLyq','yxvKAw8TDgv4Da','Aw5JBhvKzxm','rMv0y2HPBMCGBa','wNv1B0y','BNrjzcbMB3iGBa','zw51BwvYywjSzq','r0fnrv9dt0rfuW','EuzIBvK','Evr4Avm','BZiUBxaZ','yxv0Af90B2TLBG','sePcEK4','vefuvvm','qvrb','vNfvv20','uKrhCe4','BwvZC2fNzq','t2jlr1y','BwuGy29KztOG','weXqre0','A3rKzwu','z2vmAxn0zw5LCG','ve16DeW','u0rlx0Dfvf9srq','igrHDge','rZaWmq','uM1Zwgu','oIbPBMrLEca','ENHOvfq','txDOwvu','u2P2CLe','yxv0AfrVA2vU','tLLfAvu','ugDMDxy','qxvKAw8','z0v1Bwu','w0XPDMvDiefUCW','CwnywNq','rZaWmW','vgHLihf1AwnRia','yxbPqMfZzvvYBa','wgXiC2O','yxvKAw8VzwXLCa','qxnfBLi','BLP3s2e','Auzeru0','tu9ds19hmtiZ','DgeGzM91BMqGzG','BMvXD1K','yvj0qKO','sw52ywXPzcbNyq','ywXSB3DLze9YAq','s096vhK','vMXdBeS','yuTeDLK','BMnLlxnLBNrLBG','q09nufvurvi','BgvUz3rO','wuf4ue4','rZeXmG','ienVCMuGAw5PDa','s2HoDKy','CgXHExm','tM8Gy29YCMvJDa','AgfZqxvKAw8','s3rAzM8','zMLSDgvY','AujHC2vvCMWGBW','ywrKrxzLBNrmAq','uNPtDMO','x0zpvu5e','AxndB3jYzwn0','tu9ds19hmtiW','teLLtva','zgLV','refVAMe','u2rgrK8','BMnLlxDVCMqTyq','C3nHz2uGzNjVBq','refuqv9fuLjpuG','q2H14BUrAq','rZaWna','A21Zsuu','vvfqEfC','tK9ux1jfqurz','DfjjwwW','DgjHBgWGAw4GDa','DgvTCW','xsbszxnVBhzLza','Cw1NBxy','u0rlieLMCMfTzq','DgLVBJeUBxaZ','v2XdDeK','lcbNyw1Lx2nVza','svPlEwu','C2vXDwvUy2vFDW','y2XPzw50sxrLBq','zMvLzgjHy2S','vw1LEfu','qu5tv0vs','wwH6q3K','q2HPBq','DejArLC','CgfYDhm','B1n2C0W','yNjVD24','C2v0DxbnzxnZyq','Bw9JAY1XDwL6lq','B3jKief1zgLV','s0ztEgK','yxvKAw8VC2vUDa','u2HL','Bg92zq','wu5rCuy','CM5PBMCGrw5NBa','BfLcq1q','BNvTyMvY','q3f2BNu','sxjxA1a','zg9NlG','t3b0Aw9UCW','zwqGBg9JywXSEq','BMeUBxaZ','zdOGBw9Kzt0','t2Huzg0','CMvXDwvZDf9Pza','Aff4Bfy','Au9HCha','wefVs2K','yxbPx2jHC2vFDq','y2HLy2TbBNn3zq','AwfSAxPLza','zwn0igfUC3DLCG','vNnyrNm','tgTUqvy','B3uGy2HVC2uGiG','DgLTzv9ZCgvUDa','zxi6ia','s2TcreO','qMXVy2TLzcbTzq','Bu9qCeG','vLHhCvi','whvWEuG','BurwtgO','tu9ds19hmdaY','CvPKr00','w0XPDMvDiezHAq','BYbZy2HVB2WGzq','Ee1dAhu','C2fUAxrPEMvgBW','qMLzvwC','tMDLrxC','wvfWENa','AgfUzgXLq2HLyW','DwrPBY1HBgW','u1vctuLux0vsuG','q29UDgvUDc1uEq','igLZici','y29UzMLN','y29YCMvJDa','y1j3txa','tu9ds19hmteY','w1nKA0LMCMfTzq','q2JdSW','DMvYEsbKyxKU','lMPWzW','wMDHAxy','vxr4CNO','ExjzyNa','uxvPEIbbDwrPBW','AgfZt3DUuhjVCa','su5wquXjrf9ntW','Dgv4Dc10zxH0','Aw1Hz2vZl2nHDa','twPIAge','zMLUzwq','zwqGBw9JAYbKyq','DhjPBq','v09steq','uvzgC2y','uejMvfK','t1v5rvi','r3b1Cw4','Bw9Kzq','CxvLC3rPB25FAq','ANnVBG','y29TCgXLDgvKuq','vgTfvK8','r3jHCgu','B2jQzwn0','v1bKrvi','v3fgsvi','C2vUzevYCM9Y','y2fSBa','thHLqM8','r1zgthy','zfnhvem','tM9lwNy','B3b0Aw9UCW','u0rlx0fou1DfuG','wKrgrg4','sg1UtxK','x19LC01VzhvSzq','rZeXmq','D3nyr0O','ywjur2m','AgfUzgXLsw5PDa','ChjVDg90ExbL','C3mX','C2XLzxbPBMCU','BKHOugS','B3i6ia','zMXVB3i','rNbPz2K','shxHUR8','BMnLlxDVCMq','uKvuuLLFrvjstW','y3jLyxrLu2rRtq','qvbqteu','lvrLEhq','vfDzvK0','yxnZAwDUBwvUDa','BNmVBgL2zs9HBG','wuXUD2m','Aw1Hz2uTDgv4Da','wxbttLa','q1jjC1y','u0rlx1jfqurz','AxnbCNjHEq','yxvKAw8VAgvSBa','DwLnvgq','t3jHBMDL','sKfTq1y','DxLqD2C','B3biEKm','uLjpuG','BezxEg8','AxzLigrHDge6ia','DgLVBJiUBxaZ','DMfSDwu','EgH0B24','BvnJExe','DhLWzq','BuHKAxG','DLzYC0K','D0nsvxO','tM8GBw9JAYbKyq','C3r1zgvUDf9Pza','zw5JztmUBxaZ','uKvtvuXu','u2vntfa','Aw9UCW','BMfTzq','DxrLCI5TCdm','rhfpBLK','BurRyM4','rxHNthe','z1znC0G','t1vora','C3CY','C1vvBg0','C3r1zgvUDeLK','u0jozvC','y2f0','BwHqBMm','s3vdqw4','u1vmva','sog7KYbdAmoTie1PBG','Evn5BMm','ANvTChmGB3zLCG','DgeGzM9Yia','v0LZyM4','yNjVD24GzM94ia','igL0zw1Zlca','ue9dB2O','zeLYvMy','zuXqy3i','BLbKveq','zMfqz3q','u2TrC0q','iIbTyxrJAgvZia','uMvJzwL2zwq6ia','vgJHU48','t0rPyu4','tMPiuha','Cu1PBNC','qNbxy3m','reHcwgu','CMndtvy','zgvIDwC','ufziAKS','EMvK','BguUANbN','sevmte8','CMLNAw4','uvD3BMW','C3CZ','ywDL','y2uTyxvKAw8TmG','seX0yuG','vw5RBM93BIbTzq','u2vXDwvUy2uGvW','ugr0rve','txKGyNjVDgHLCG','DNnsAg4','vNznCe0','DhDYyKe','ysb04BURicjizwXS','z2v0t3DUuhjVCa','BhPJuvK','yKLeqwO','4BQJBMGGy29Uig3dQa','wuv0u0G','C2v0','Bw9JAY1Zzxf1zq','DvPmD28','vLjTvNq','zKPMzuy','tu9ds19hmdaX','t1rFrK9vtKq','mtK3mJyZnKHnwxvXBG','sLnoDMe','Dg9mB3DLCKnHCW','C2fUAxrPEMvKsq','4PYfienVCNjLy3qH','teLAruq','ywHruw4','q2f0','zw5JztiUBxaZ','DeXPC3rLBMvY','BgL2zq','ywvzs0G','ywLxA2m','EgjTAve','B1LLC3q','r2TQAe4','vM9Vv0q','BM93','w0DHBwveyxrHsa','DxvnCfu','zhbwswy','Bg9N','tMHV','yw5ZD2vYici','yNnIr0G','Dhr3yLe','uLLQqNK','vvDktNa','zw50zw5Jzq','Dw5KzwzPBMvK','Dhj1zq','zNvUy3rPB24','A0fUC3DLCG','AND4r1e','tu9ds19ot1rFrG','zgPRzgi','BuH1uw0','tM8Gzgf0ysbSBW'];a0_0x13ba=function(){return _0x233fe8;};return a0_0x13ba();}const a0_0x587cb7=a0_0x3575;function a0_0x3575(_0xf40628,_0x19a82f){_0xf40628=_0xf40628-0x1d7;const _0x13baf7=a0_0x13ba();let _0x3575ce=_0x13baf7[_0xf40628];if(a0_0x3575['kQQcnv']===undefined){var _0xab8f8e=function(_0x4af7d3){const _0x434fbe='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4ec5d4='',_0x353715='';for(let _0x58a9f0=0x0,_0x1c1c0b,_0x215bbf,_0x4a832d=0x0;_0x215bbf=_0x4af7d3['charAt'](_0x4a832d++);~_0x215bbf&&(_0x1c1c0b=_0x58a9f0%0x4?_0x1c1c0b*0x40+_0x215bbf:_0x215bbf,_0x58a9f0++%0x4)?_0x4ec5d4+=String['fromCharCode'](0xff&_0x1c1c0b>>(-0x2*_0x58a9f0&0x6)):0x0){_0x215bbf=_0x434fbe['indexOf'](_0x215bbf);}for(let _0xd65f84=0x0,_0x3165c4=_0x4ec5d4['length'];_0xd65f84<_0x3165c4;_0xd65f84++){_0x353715+='%'+('00'+_0x4ec5d4['charCodeAt'](_0xd65f84)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x353715);};a0_0x3575['zsKJYT']=_0xab8f8e,a0_0x3575['whPKxJ']={},a0_0x3575['kQQcnv']=!![];}const _0x52e412=_0x13baf7[0x0],_0x3dcc83=_0xf40628+_0x52e412,_0x3cb92c=a0_0x3575['whPKxJ'][_0x3dcc83];return!_0x3cb92c?(_0x3575ce=a0_0x3575['zsKJYT'](_0x3575ce),a0_0x3575['whPKxJ'][_0x3dcc83]=_0x3575ce):_0x3575ce=_0x3cb92c,_0x3575ce;}(function(_0x255538,_0x546f3f){const _0x3d79c4=a0_0x3575,_0x48d0cd=_0x255538();while(!![]){try{const _0x33e8b8=-parseInt(_0x3d79c4(0x47b))/0x1*(-parseInt(_0x3d79c4(0x3fe))/0x2)+-parseInt(_0x3d79c4(0x4c0))/0x3+-parseInt(_0x3d79c4(0x355))/0x4+parseInt(_0x3d79c4(0x4d7))/0x5*(-parseInt(_0x3d79c4(0x1f6))/0x6)+parseInt(_0x3d79c4(0x38a))/0x7+-parseInt(_0x3d79c4(0x4d0))/0x8+parseInt(_0x3d79c4(0x48c))/0x9;if(_0x33e8b8===_0x546f3f)break;else _0x48d0cd['push'](_0x48d0cd['shift']());}catch(_0x4da583){_0x48d0cd['push'](_0x48d0cd['shift']());}}}(a0_0x13ba,0x87a89),!function(_0x5de6ad,_0x243eca){const _0x5bbc91=a0_0x3575,_0x4d183a={'ahQQn':function(_0x2994ad,_0x44e58c){return _0x2994ad==_0x44e58c;},'WEWiD':_0x5bbc91(0x2d2),'UQPxW':'function','RUrYI':function(_0x431781,_0x218e1c){return _0x431781==_0x218e1c;},'VqUWm':function(_0x429616){return _0x429616();},'fJfeF':function(_0x4fb472){return _0x4fb472();}};_0x4d183a[_0x5bbc91(0x35b)](_0x4d183a['WEWiD'],typeof exports)&&_0x4d183a[_0x5bbc91(0x3b5)]==typeof module?module[_0x5bbc91(0x206)]=_0x243eca():_0x4d183a['ahQQn'](_0x4d183a[_0x5bbc91(0x268)],typeof define)&&define[_0x5bbc91(0x4c4)]?define([],_0x243eca):_0x4d183a[_0x5bbc91(0x485)](_0x4d183a['WEWiD'],typeof exports)?exports[_0x5bbc91(0x4e9)]=_0x4d183a[_0x5bbc91(0x223)](_0x243eca):_0x5de6ad[_0x5bbc91(0x4e9)]=_0x4d183a[_0x5bbc91(0x352)](_0x243eca);}(Object(a0_0x587cb7(0x372)!=typeof self?self:this),()=>((()=>{'use strict';const _0x41c3f4=a0_0x587cb7,_0x24a5c7={'VlClK':_0x41c3f4(0x225),'QjCdd':'gquVA','ktHzQ':_0x41c3f4(0x397),'iXohe':function(_0x2b8d8d,_0x212b0e){return _0x2b8d8d>_0x212b0e;},'SdFFO':function(_0x15c680,_0x2382b4){return _0x15c680+_0x2382b4;},'zxhTT':_0x41c3f4(0x2d2),'UWJNp':_0x41c3f4(0x374),'BcBPu':function(_0x5d01f2,_0x1482a2,_0xe0e32f){return _0x5d01f2(_0x1482a2,_0xe0e32f);},'aRtBJ':function(_0x45a4a9,_0x52e603){return _0x45a4a9===_0x52e603;},'ljmUq':_0x41c3f4(0x2d3),'wajUj':function(_0x308126,_0x38e967){return _0x308126(_0x38e967);},'NBtay':function(_0x3cb20e,_0x538341){return _0x3cb20e==_0x538341;},'ODOhn':function(_0x567998,_0x3b6d9e){return _0x567998 in _0x3b6d9e;},'lYBCT':function(_0x49e549,_0x3fc97d){return _0x49e549??_0x3fc97d;},'LFWnT':function(_0x276a9,_0x6831c){return _0x276a9!==_0x6831c;},'FDRcK':'nnKkU','PVHjK':function(_0x14a560,_0x560c04){return _0x14a560??_0x560c04;},'RzSvj':_0x41c3f4(0x435),'AlPMy':function(_0x5945cb,_0x39b8db){return _0x5945cb===_0x39b8db;},'dHvqQ':_0x41c3f4(0x212),'NqmSE':_0x41c3f4(0x22e),'PWnRz':_0x41c3f4(0x1f5),'XWmIO':_0x41c3f4(0x23b),'dIrVf':_0x41c3f4(0x266),'NjHPp':_0x41c3f4(0x3ac),'mcVmC':_0x41c3f4(0x2e0),'ZlQbN':_0x41c3f4(0x250),'xMChu':_0x41c3f4(0x4a7),'dMxuh':_0x41c3f4(0x442),'LknAV':'G123','HeSsx':function(_0x5eb742,_0x381c8e){return _0x5eb742*_0x381c8e;},'ynuLI':_0x41c3f4(0x377)+_0x41c3f4(0x317),'wcmmw':_0x41c3f4(0x28b),'zGXdb':function(_0x3a5a1b,_0x354cec){return _0x3a5a1b-_0x354cec;},'TkEVO':_0x41c3f4(0x4aa),'DcpFz':_0x41c3f4(0x4d2),'Rqmnf':_0x41c3f4(0x38e),'wQbNZ':_0x41c3f4(0x3e8),'pZzKe':_0x41c3f4(0x404),'YLnwc':'jMcRV','aeYKH':_0x41c3f4(0x2df),'bcxxg':_0x41c3f4(0x1ee)+'Text','mDkbn':_0x41c3f4(0x2be)+_0x41c3f4(0x2f0),'lPKUU':_0x41c3f4(0x1ee)+_0x41c3f4(0x237),'AHhJf':'quiz','wAgmR':'Quiz\x20Image'+_0x41c3f4(0x2f0),'HeFjB':_0x41c3f4(0x1ee)+_0x41c3f4(0x1e8),'LjdaW':_0x41c3f4(0x342)+_0x41c3f4(0x47a),'viuic':_0x41c3f4(0x274)+_0x41c3f4(0x47a),'ooyzw':_0x41c3f4(0x3cf)+_0x41c3f4(0x371),'TWYVM':_0x41c3f4(0x3cf)+'entence\x20Au'+_0x41c3f4(0x25f),'zMzcY':_0x41c3f4(0x412)+_0x41c3f4(0x371),'WSAzE':function(_0x165099,_0x5f55bc){return _0x165099===_0x5f55bc;},'pCJER':'oNODv','YAxPN':function(_0x3840cf,_0x33f2b7){return _0x3840cf===_0x33f2b7;},'hyauh':function(_0x8350ab,_0xf62ed0){return _0x8350ab!==_0xf62ed0;},'SRyct':_0x41c3f4(0x20a),'oYest':_0x41c3f4(0x264),'Esfiu':_0x41c3f4(0x2c0)+'DE','loWKD':_0x41c3f4(0x43c)+'ATA\x20only\x20a'+_0x41c3f4(0x3b6)+_0x41c3f4(0x3af)+'de','ZDJVK':_0x41c3f4(0x43b)+_0x41c3f4(0x35a),'iovTv':_0x41c3f4(0x269),'VXGqR':_0x41c3f4(0x37a)+'aded','yYcIx':'wOtQw','iOapp':function(_0x593727,_0x175bb6){return _0x593727>=_0x175bb6;},'jwxGQ':function(_0x257540,_0x12631f){return _0x257540<_0x12631f;},'zruSA':_0x41c3f4(0x336),'RDGpN':_0x41c3f4(0x20f),'TiSFf':function(_0x12d4f1,_0x378a4f){return _0x12d4f1!==_0x378a4f;},'vOpTn':_0x41c3f4(0x282),'AQVSr':_0x41c3f4(0x2b0)+'OR','XAoKi':_0x41c3f4(0x43a)+'submit\x20ans'+_0x41c3f4(0x1fe),'vivdY':'QUESTION_N'+_0x41c3f4(0x354),'eFzNp':function(_0x2f9d64,_0x58620e){return _0x2f9d64>_0x58620e;},'NgeEw':function(_0x55b3ce,_0xbb9021){return _0x55b3ce-_0xbb9021;},'aKDvY':function(_0x1be133,_0x21b54c){return _0x1be133===_0x21b54c;},'KKtUy':_0x41c3f4(0x46b),'NiPRu':_0x41c3f4(0x2ed)+'R','eLPjG':_0x41c3f4(0x387)+_0x41c3f4(0x25b),'mDVLj':_0x41c3f4(0x4b8)+_0x41c3f4(0x39e),'sxnXP':function(_0x2bcf31,_0x1ed4aa,_0x5ba323){return _0x2bcf31(_0x1ed4aa,_0x5ba323);},'oYgcD':function(_0x280dd9,_0x217911){return _0x280dd9!==_0x217911;},'UFdRU':'FLPQg','YgsAK':'CONFIG_ERR'+'OR','lsjEv':'null','SEvXh':function(_0x3bdbd2,_0x258084){return _0x3bdbd2===_0x258084;},'AsEnR':'JSNva','HiVLV':function(_0x237390,_0x57bcbe){return _0x237390<_0x57bcbe;},'kvepA':function(_0x5f3c45,_0x5eddd1){return _0x5f3c45*_0x5eddd1;},'VYEWb':function(_0x4e57dc,_0x2c8c64){return _0x4e57dc(_0x2c8c64);},'dfMjy':function(_0x3aeb46,_0x2c5e5b){return _0x3aeb46!==_0x2c5e5b;},'qhPTK':_0x41c3f4(0x26f)+'\x20Core\x20init'+_0x41c3f4(0x298),'SmnfR':_0x41c3f4(0x218),'lXskD':function(_0x523ca0,_0xe3bc1b){return _0x523ca0===_0xe3bc1b;},'BTatG':_0x41c3f4(0x4e5),'fVEte':_0x41c3f4(0x2c3),'QWwnl':'INIT_ERROR','dFaWp':_0x41c3f4(0x45e),'OUyER':_0x41c3f4(0x3a4)+_0x41c3f4(0x258)+_0x41c3f4(0x47c)+_0x41c3f4(0x3b4),'csTex':'POST','nZwKa':function(_0x208435,_0x15b0b6){return _0x208435??_0x15b0b6;},'VXDqH':_0x41c3f4(0x2b5),'UZUfk':_0x41c3f4(0x4e6),'Esthi':function(_0x31b066,_0x2ac40f){return _0x31b066>_0x2ac40f;},'sUUlm':function(_0x41d256,_0x152b54){return _0x41d256??_0x152b54;},'ystwn':_0x41c3f4(0x440),'RYjBy':function(_0x54e191,_0x119c0d){return _0x54e191===_0x119c0d;},'GRWSJ':'qVRTT','bHwPj':_0x41c3f4(0x26f)+_0x41c3f4(0x438),'cNKsr':'GwmHC','nJDTA':function(_0x4a09a2,_0x2c1f05){return _0x4a09a2(_0x2c1f05);},'uiMTd':function(_0x31ed55,_0x5d416e){return _0x31ed55!=_0x5d416e;},'NmRZL':_0x41c3f4(0x372),'hhmiz':function(_0x5c76a3,_0x17cc8c){return _0x5c76a3===_0x17cc8c;},'xYiju':_0x41c3f4(0x373),'LSBlL':_0x41c3f4(0x434),'jgCLh':function(_0x430478,_0x50fa15,_0x185525,_0x5c053f){return _0x430478(_0x50fa15,_0x185525,_0x5c053f);},'ZnLZN':'maIcA','YfHXJ':_0x41c3f4(0x3e1),'vyCIX':_0x41c3f4(0x1e3)+_0x41c3f4(0x392),'kaDdy':function(_0x445d02,_0x193047,_0x3c816b){return _0x445d02(_0x193047,_0x3c816b);},'fPIrV':function(_0x1eee6b,_0x36a530){return _0x1eee6b(_0x36a530);},'wpewm':function(_0xc585c9,_0x2c7b69){return _0xc585c9!=_0x2c7b69;},'CsxsO':_0x41c3f4(0x280)+_0x41c3f4(0x2c1),'bewEs':_0x41c3f4(0x47e)+_0x41c3f4(0x496)+_0x41c3f4(0x3b1),'HJBzN':_0x41c3f4(0x385),'rGEbc':_0x41c3f4(0x2eb),'NeHYj':'2\x20+\x202\x20=\x20?','fsxlW':_0x41c3f4(0x2b8),'nNnkr':_0x41c3f4(0x27a),'bsbGH':'mock-quiz-'+_0x41c3f4(0x215),'CCOer':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x4e3)+_0x41c3f4(0x270),'EzipB':'Apple','ugmiz':_0x41c3f4(0x2fc),'tRIYl':_0x41c3f4(0x2d1),'gpLdw':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x4e3)+_0x41c3f4(0x303),'oSvsL':_0x41c3f4(0x3a3),'zByOx':_0x41c3f4(0x35c),'qcyKy':_0x41c3f4(0x459),'qZdGM':_0x41c3f4(0x463),'KkBDJ':_0x41c3f4(0x280)+_0x41c3f4(0x4c2),'vyzPG':_0x41c3f4(0x4a8)+_0x41c3f4(0x43e)+_0x41c3f4(0x348)+'o\x22','YPPZO':'https://ex'+_0x41c3f4(0x437)+_0x41c3f4(0x2fa)+_0x41c3f4(0x4b6),'uyPwg':_0x41c3f4(0x208)+'ample.com/'+'audio/hell'+_0x41c3f4(0x21e),'KUANh':_0x41c3f4(0x280)+_0x41c3f4(0x2f5),'BiYUg':_0x41c3f4(0x208)+_0x41c3f4(0x437)+'images/app'+_0x41c3f4(0x339),'tBZFW':_0x41c3f4(0x46e)+_0x41c3f4(0x3c0),'onTJR':'Táo','MwhYU':_0x41c3f4(0x265),'iFDEM':_0x41c3f4(0x36b),'lUkmZ':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x2c2)+'.jpg','JihMj':_0x41c3f4(0x32f),'ExgLq':'Chuột','XlHsj':_0x41c3f4(0x280)+_0x41c3f4(0x497),'OWbqI':_0x41c3f4(0x49e)+_0x41c3f4(0x34c)+'o','wKOhE':_0x41c3f4(0x208)+'ample.com/'+'images/dog'+_0x41c3f4(0x2ba),'nKpsr':_0x41c3f4(0x34f)+_0x41c3f4(0x2ec),'ObKGV':_0x41c3f4(0x444),'DrFgt':_0x41c3f4(0x2ef),'mScyq':_0x41c3f4(0x318),'wrQhY':_0x41c3f4(0x33d),'DPEmL':_0x41c3f4(0x2c7),'qmgmv':_0x41c3f4(0x34f)+_0x41c3f4(0x262)+_0x41c3f4(0x40e),'GpVia':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x488)+_0x41c3f4(0x28f),'mhPnc':_0x41c3f4(0x34f)+'nce-word-a'+'udio-4','WPJKD':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x45f)+_0x41c3f4(0x312),'Ztzzk':_0x41c3f4(0x34f)+_0x41c3f4(0x262)+_0x41c3f4(0x2af),'RmsXe':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x23f)+'hant.mp3','VODcc':_0x41c3f4(0x34f)+_0x41c3f4(0x24c)+'ce','vsRhn':'ss1','asqeY':_0x41c3f4(0x214)+_0x41c3f4(0x287)+_0x41c3f4(0x37c),'KhNvF':'learning','nPdTD':_0x41c3f4(0x3c8),'ETFtY':_0x41c3f4(0x285),'DRAKv':'ss2','eaWsL':'The\x20cat\x20is'+_0x41c3f4(0x494),'RAWzv':_0x41c3f4(0x3dc),'gAUaD':'cat','fHKpS':_0x41c3f4(0x2e6),'DAoja':_0x41c3f4(0x381)+_0x41c3f4(0x2a8)+_0x41c3f4(0x2b9),'neqwY':'goes','WqFIR':_0x41c3f4(0x1f4),'yZHUM':'day.','Xbrqi':'school','CRIsV':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x283)+_0x41c3f4(0x44a),'BpWcs':_0x41c3f4(0x34f)+_0x41c3f4(0x24c)+'ce-audio-4','HLtaH':_0x41c3f4(0x344)+_0x41c3f4(0x418)+_0x41c3f4(0x26b)+'he\x20park.','YhzCy':'brother','QfNiN':_0x41c3f4(0x253),'IEGRj':_0x41c3f4(0x462),'eZrGU':'the','nHhPk':'park.','avWyG':_0x41c3f4(0x34f)+_0x41c3f4(0x24c)+'ce-audio-a'+'ll','VsXFs':_0x41c3f4(0x23c)+_0x41c3f4(0x325)+_0x41c3f4(0x322)+'\x20the\x20lazy\x20'+'dog.','DOQPy':'brown','WIsbn':_0x41c3f4(0x477),'xDjaC':_0x41c3f4(0x44c),'qMinw':'over','Fpigi':_0x41c3f4(0x419),'nauUG':_0x41c3f4(0x28c),'YsLnK':_0x41c3f4(0x4ab),'IfgBM':_0x41c3f4(0x208)+_0x41c3f4(0x437)+_0x41c3f4(0x283)+_0x41c3f4(0x30d),'kxYpH':function(_0x341c0d,_0x1cd26f){return _0x341c0d==_0x1cd26f;},'ahFbx':function(_0x106d31,_0x42ec47){return _0x106d31 in _0x42ec47;},'hoEkO':_0x41c3f4(0x43c)+_0x41c3f4(0x222),'elRUi':_0x41c3f4(0x421)+_0x41c3f4(0x278),'NYEiU':_0x41c3f4(0x22c)+_0x41c3f4(0x31f),'FOdDt':_0x41c3f4(0x2f8),'wsXGJ':_0x41c3f4(0x383)+_0x41c3f4(0x300),'nJbRZ':'SDK_FINAL_'+'RESULT','OrEfR':_0x41c3f4(0x3ee),'SIKiW':function(_0x2a543a,_0x18c9e9){return _0x2a543a===_0x18c9e9;},'Rjhxs':function(_0xb4a3b5,_0x2193fb){return _0xb4a3b5<_0x2193fb;},'KtZfo':function(_0x49a24b,_0x5e1b47){return _0x49a24b*_0x5e1b47;},'OkBxG':function(_0x5d0a99,_0x4b4719){return _0x5d0a99!==_0x4b4719;},'mHuQm':_0x41c3f4(0x4af)};var _0x4eba57={0x95(_0x4a207d,_0x1b7dc6){const _0x1f5be5=_0x41c3f4,_0x25ed87={'Ngcrt':function(_0x29156b,_0x537663){const _0x3fa5e4=a0_0x3575;return _0x24a5c7[_0x3fa5e4(0x3cc)](_0x29156b,_0x537663);},'Kgypa':_0x24a5c7[_0x1f5be5(0x410)],'NVJlm':_0x24a5c7['ynuLI'],'pNZmn':_0x24a5c7[_0x1f5be5(0x4c7)],'lPPKC':function(_0x5d5a42,_0x329f3b){return _0x24a5c7['wajUj'](_0x5d5a42,_0x329f3b);},'ACPkY':function(_0x1cae4b,_0x248255){const _0xba46ab=_0x1f5be5;return _0x24a5c7[_0xba46ab(0x3b2)](_0x1cae4b,_0x248255);},'Qcjtu':function(_0x2ca512,_0x3f3669){const _0x22a75c=_0x1f5be5;return _0x24a5c7[_0x22a75c(0x4dd)](_0x2ca512,_0x3f3669);},'SeMLP':_0x24a5c7[_0x1f5be5(0x2d0)],'ritcZ':_0x24a5c7['zxhTT'],'ttwbQ':function(_0x469788,_0x231841){const _0x38dca7=_0x1f5be5;return _0x24a5c7[_0x38dca7(0x449)](_0x469788,_0x231841);},'SDKPU':_0x24a5c7['DcpFz'],'dpVIf':function(_0x3d614f,_0x11b411){return _0x3d614f??_0x11b411;},'hdJZR':function(_0x4b69ed,_0xfc61a6){return _0x4b69ed(_0xfc61a6);},'XupyH':function(_0x11004b,_0x554c6f){return _0x11004b===_0x554c6f;},'gRWZQ':function(_0x2f4dbe,_0x384650){return _0x24a5c7['wajUj'](_0x2f4dbe,_0x384650);},'yrYbp':'No\x20correct'+_0x1f5be5(0x1f3)+'fined','epPmV':_0x1f5be5(0x289),'YpSNP':function(_0x18d65b,_0x23accf){return _0x24a5c7['NBtay'](_0x18d65b,_0x23accf);},'amOBF':_0x24a5c7[_0x1f5be5(0x467)],'CKmsb':'G001','ODiaN':_0x1f5be5(0x1f5),'MUFQh':_0x24a5c7[_0x1f5be5(0x473)],'ExBMb':_0x1f5be5(0x20f),'ZxyAz':_0x1f5be5(0x2e0),'tDVbO':_0x24a5c7['xMChu'],'QVFsf':_0x24a5c7[_0x1f5be5(0x4d8)],'bIDAj':_0x24a5c7[_0x1f5be5(0x3d9)],'wcWjd':_0x24a5c7[_0x1f5be5(0x209)],'TKNKD':_0x24a5c7['LknAV']};if(_0x24a5c7[_0x1f5be5(0x449)](_0x24a5c7['YLnwc'],_0x24a5c7[_0x1f5be5(0x2f4)])){const _0x5ef409=_0x142067[_0x1f5be5(0x2e9)](_0x25ed87['Ngcrt'](_0x41adc6[_0x1f5be5(0x1d8)](),_0x189c5d['length'])),_0x3e6acc=_0x9677a8[_0x5ef409];_0x2bf4b7[_0x1f5be5(0x458)](_0x3e6acc),_0x2fb40f[_0x1f5be5(0x468)](_0x5ef409,0x1);}else{function _0x54d5f5(_0x2ac7a3){const _0x57b84c=_0x1f5be5,_0x32b894={};_0x32b894['fahyl']=_0x24a5c7[_0x57b84c(0x24a)];const _0x21b6ba=_0x32b894;if(_0x24a5c7[_0x57b84c(0x3d4)]!==_0x24a5c7['ktHzQ'])for(let _0x2bea1c=_0x2ac7a3[_0x57b84c(0x24e)]-0x1;_0x24a5c7[_0x57b84c(0x37b)](_0x2bea1c,0x0);_0x2bea1c--){const _0x23bd92=Math[_0x57b84c(0x2e9)](Math[_0x57b84c(0x1d8)]()*_0x24a5c7[_0x57b84c(0x261)](_0x2bea1c,0x1));[_0x2ac7a3[_0x2bea1c],_0x2ac7a3[_0x23bd92]]=[_0x2ac7a3[_0x23bd92],_0x2ac7a3[_0x2bea1c]];}else this['boundMessa'+_0x57b84c(0x42d)]&&(_0x252a8e[_0x57b84c(0x213)+_0x57b84c(0x35e)](_0x21b6ba['fahyl'],this[_0x57b84c(0x465)+_0x57b84c(0x42d)]),this[_0x57b84c(0x465)+'geHandler']=null),this[_0x57b84c(0x1fa)+'ems'][_0x57b84c(0x3e6)](),this[_0x57b84c(0x1e6)+'s']['clear'](),this[_0x57b84c(0x36a)]('info',_0x57b84c(0x26f)+_0x57b84c(0x438));}const _0x16ab9a={};_0x16ab9a[_0x1f5be5(0x304)]=!0x0;const _0x42afe4={};_0x42afe4[_0x1f5be5(0x311)]=_0x1f5be5(0x342)+_0x1f5be5(0x281),_0x42afe4[_0x1f5be5(0x38c)]=_0x1f5be5(0x274)+'ord',_0x42afe4[_0x1f5be5(0x255)]=!0x0,(Object[_0x1f5be5(0x1ea)+_0x1f5be5(0x41e)](_0x1b7dc6,_0x24a5c7['aeYKH'],_0x16ab9a),_0x1b7dc6[_0x1f5be5(0x21b)]=void 0x0,_0x1b7dc6['getGameCat'+'egory']=function(_0x4946cd){const _0x597d67=_0x1f5be5;return _0x1b7dc6['GAME_CODES'][_0x4946cd]?.[_0x597d67(0x38c)]||_0x597d67(0x45e);},_0x1b7dc6[_0x1f5be5(0x2aa)+'rClient']=function(_0x5bc12f,_0x561249){const _0x459c89=_0x1f5be5,_0x27300e={'VFQki':_0x24a5c7[_0x459c89(0x231)],'Gpuqn':_0x24a5c7[_0x459c89(0x370)],'dSGTC':function(_0x1eafb3,_0x48d044,_0x8bcf61){const _0x27de0e=_0x459c89;return _0x24a5c7[_0x27de0e(0x41d)](_0x1eafb3,_0x48d044,_0x8bcf61);},'vVrsI':function(_0x3224d5,_0x72646a){const _0x235e33=_0x459c89;return _0x24a5c7[_0x235e33(0x246)](_0x3224d5,_0x72646a);},'zjcNx':_0x24a5c7[_0x459c89(0x3aa)],'BcKPQ':function(_0x52722f,_0x40a239){const _0x37530c=_0x459c89;return _0x24a5c7[_0x37530c(0x42b)](_0x52722f,_0x40a239);},'KQbBr':function(_0x5705ac,_0xa48327){return _0x24a5c7['NBtay'](_0x5705ac,_0xa48327);},'LIeMP':function(_0x55cb7d,_0x3707a9){const _0x487293=_0x459c89;return _0x24a5c7[_0x487293(0x429)](_0x55cb7d,_0x3707a9);},'lsXuB':function(_0x6cfb75,_0x3aef0a){const _0x3a528b=_0x459c89;return _0x24a5c7[_0x3a528b(0x288)](_0x6cfb75,_0x3aef0a);},'HmnMy':_0x459c89(0x396),'JvZyf':function(_0x9cf7bd,_0x47a131){return _0x24a5c7['LFWnT'](_0x9cf7bd,_0x47a131);},'IJmmA':_0x459c89(0x39b),'iszVV':_0x24a5c7[_0x459c89(0x448)],'rcCMV':function(_0x171497,_0x1b7bbe){return _0x171497!==_0x1b7bbe;},'aeuwQ':function(_0x3306ca,_0x20c504){const _0x1852f2=_0x459c89;return _0x24a5c7[_0x1852f2(0x337)](_0x3306ca,_0x20c504);},'jQdXh':_0x24a5c7[_0x459c89(0x25a)],'vnpin':_0x459c89(0x3d1),'PBfTY':function(_0x16f7a6,_0x1e4fd9){const _0xfbd2c1=_0x459c89;return _0x24a5c7[_0xfbd2c1(0x499)](_0x16f7a6,_0x1e4fd9);},'eLPcr':function(_0xdd441,_0x43bee8){return _0xdd441<_0x43bee8;},'ttLCX':function(_0x523f37,_0x987028){return _0x523f37*_0x987028;},'QCbdx':_0x24a5c7['dHvqQ'],'vvRiN':_0x459c89(0x347),'nskYB':function(_0x3103ec,_0x1cbd3c){return _0x3103ec<_0x1cbd3c;}};if(!Array['isArray'](_0x561249))return[];switch(_0x5bc12f){case _0x24a5c7[_0x459c89(0x401)]:return function(_0x355953){const _0x1f7313=_0x459c89,_0x1daaf5={'TBoZJ':_0x25ed87[_0x1f7313(0x49c)],'yTxiS':_0x25ed87[_0x1f7313(0x407)],'unVvf':function(_0x45a619,_0x484bee){return _0x45a619!==_0x484bee;},'Csrbl':_0x25ed87[_0x1f7313(0x461)],'lFWxo':function(_0x1d6e8f,_0x13f55f){const _0x224981=_0x1f7313;return _0x25ed87[_0x224981(0x46f)](_0x1d6e8f,_0x13f55f);}};return _0x355953[_0x1f7313(0x3b9)](_0x4ce4c1=>{const _0x514385=_0x1f7313,_0x18ade7={};_0x18ade7[_0x514385(0x31e)]=_0x1daaf5[_0x514385(0x478)],_0x18ade7[_0x514385(0x40b)]=_0x1daaf5[_0x514385(0x21d)];const _0x24628f=_0x18ade7;if(_0x1daaf5['unVvf'](_0x1daaf5[_0x514385(0x3ae)],_0x1daaf5['Csrbl'])){const _0x10ab8c=(0x0,_0x49acf1[_0x514385(0x203)+'a'])(this[_0x514385(0x3eb)]);_0x10ab8c?(this[_0x514385(0x36a)](_0x24628f[_0x514385(0x31e)],_0x514385(0x403)+_0x514385(0x2c5)+_0x514385(0x323)+this[_0x514385(0x3eb)]),this['processDat'+'a'](_0x10ab8c[_0x514385(0x3c5)])):this[_0x514385(0x2d5)](_0x24628f['DlXsi'],_0x514385(0x30b)+_0x514385(0x244)+'or\x20'+this[_0x514385(0x3eb)],_0x580622);}else{const _0x395b58=(_0x4ce4c1[_0x514385(0x2db)]||[])[_0x514385(0x3b9)](_0x2ac080=>_0x514385(0x4aa)==typeof _0x2ac080?{'text':_0x2ac080}:_0x2ac080&&_0x514385(0x2d2)==typeof _0x2ac080?{'text':String(_0x2ac080[_0x514385(0x38e)]??'')}:{'text':String(_0x2ac080??'')});_0x1daaf5[_0x514385(0x301)](_0x54d5f5,_0x395b58);const _0x471916=_0x395b58[_0x514385(0x3b9)](_0x73ef55=>String(_0x73ef55[_0x514385(0x38e)]??'')),_0x1de5e1={};return _0x1de5e1['id']=_0x4ce4c1['id'],_0x1de5e1[_0x514385(0x49d)]=_0x4ce4c1['question'],_0x1de5e1[_0x514385(0x2db)]=_0x395b58,_0x1de5e1[_0x514385(0x3ab)+'Options']=_0x471916,_0x1de5e1;}});}(_0x561249);case _0x24a5c7[_0x459c89(0x4e8)]:return function(_0x29ca14){return _0x29ca14['map'](_0x3499c2=>{const _0x5ee922=a0_0x3575,_0x2fa946={'gJznx':function(_0x2272de,_0x517c58){return _0x2272de==_0x517c58;},'bAMCx':_0x27300e[_0x5ee922(0x498)],'yCbnB':function(_0x292ade){return _0x292ade();},'gVMsH':_0x27300e[_0x5ee922(0x2cb)],'OZkRa':function(_0x1806af,_0x1bb741,_0x5f5288){const _0x5b88ee=_0x5ee922;return _0x27300e[_0x5b88ee(0x2d9)](_0x1806af,_0x1bb741,_0x5f5288);},'xfaNd':function(_0x4d498f){return _0x4d498f();}};if(_0x27300e[_0x5ee922(0x309)](_0x27300e[_0x5ee922(0x470)],_0x27300e[_0x5ee922(0x470)])){const _0x58c941=(_0x3499c2[_0x5ee922(0x2db)]||[])[_0x5ee922(0x3b9)](_0x55415a=>_0x5ee922(0x4aa)==typeof _0x55415a?{'text':_0x55415a}:_0x55415a&&_0x5ee922(0x2d2)==typeof _0x55415a?{'text':String(_0x55415a[_0x5ee922(0x38e)]??'')}:{'text':String(_0x55415a??'')});_0x27300e['BcKPQ'](_0x54d5f5,_0x58c941);const _0x2c0559=_0x58c941['map'](_0x141a1f=>String(_0x141a1f[_0x5ee922(0x38e)]??'')),_0x5312e6={};return _0x5312e6['id']=_0x3499c2['id'],_0x5312e6['question']=_0x3499c2[_0x5ee922(0x4d9)]||_0x3499c2[_0x5ee922(0x3a0)],_0x5312e6['options']=_0x58c941,_0x5312e6[_0x5ee922(0x3ab)+_0x5ee922(0x28d)]=_0x2c0559,_0x5312e6;}else _0x2fa946[_0x5ee922(0x3c3)](_0x2fa946[_0x5ee922(0x481)],typeof _0x4bcb1b)&&_0x2fa946[_0x5ee922(0x3c3)](_0x2fa946[_0x5ee922(0x481)],typeof _0x597ddb)?_0x47a5c1[_0x5ee922(0x206)]=_0x2fa946[_0x5ee922(0x40d)](_0x1bf147):_0x2fa946[_0x5ee922(0x316)]==typeof _0x4633d9&&_0x50ce6c[_0x5ee922(0x4c4)]?_0x2fa946['OZkRa'](_0x51f3cd,[],_0x2ac4f2):_0x2fa946[_0x5ee922(0x3c3)]('object',typeof _0x566b90)?_0x1aa2c0['GameSDK']=_0x4a7779():_0x5ab2ff[_0x5ee922(0x4e9)]=_0x2fa946['xfaNd'](_0x5d130c);});}(_0x561249);case _0x24a5c7[_0x459c89(0x473)]:return function(_0x3b78b2){const _0x4a269b=_0x459c89;if(_0x27300e[_0x4a269b(0x3d7)](_0x27300e['IJmmA'],_0x27300e[_0x4a269b(0x3f7)]))return _0x3b78b2['map'](_0x596dc3=>{const _0x5138ce=_0x4a269b,_0x13576f={'opHzC':function(_0x5896e7,_0x4d6802){const _0xa261ab=a0_0x3575;return _0x27300e[_0xa261ab(0x469)](_0x5896e7,_0x4d6802);},'YPUOh':function(_0x5e162a,_0xddeeb9){return _0x5e162a==_0xddeeb9;},'faPgt':function(_0x2ed120,_0x500f8d){return _0x27300e['KQbBr'](_0x2ed120,_0x500f8d);},'SjvrQ':function(_0x49a187,_0x4c467f){return _0x49a187==_0x4c467f;},'ULPoZ':function(_0x4ea006,_0x23f9f7){const _0x529d5f=a0_0x3575;return _0x27300e[_0x529d5f(0x25e)](_0x4ea006,_0x23f9f7);},'xbmiQ':_0x5138ce(0x38e),'RpIpe':_0x27300e['VFQki'],'mHdix':function(_0x23b9b0,_0x3e1c39){return _0x27300e['lsXuB'](_0x23b9b0,_0x3e1c39);},'KtCNI':function(_0x10ad2e,_0x495acc){const _0x112434=_0x5138ce;return _0x27300e[_0x112434(0x309)](_0x10ad2e,_0x495acc);},'Cqvnu':_0x27300e[_0x5138ce(0x2de)],'SGDis':function(_0x206019,_0x1c9d7f){const _0x3733f4=_0x5138ce;return _0x27300e[_0x3733f4(0x469)](_0x206019,_0x1c9d7f);}},_0xceedaa=(_0x596dc3[_0x5138ce(0x2db)]||[])[_0x5138ce(0x3b9)](_0x9111d2=>{const _0x21a244=_0x5138ce;if('string'==typeof _0x9111d2)return{'audio':_0x9111d2};if(_0x9111d2&&_0x13576f[_0x21a244(0x37d)]==typeof _0x9111d2){if(_0x13576f['KtCNI'](_0x13576f[_0x21a244(0x28a)],_0x13576f[_0x21a244(0x28a)])){const _0x4b6624=_0x9111d2[_0x21a244(0x4d9)]||_0x9111d2['audio_url']||'';return{'audio':_0x13576f[_0x21a244(0x2ff)](String,_0x4b6624)};}else{const _0x109aee=_0x13576f[_0x21a244(0x2ff)](_0x2e3336,_0x38ce4a[_0x21a244(0x3f0)]||''),_0x2308ef={};_0x2308ef[_0x21a244(0x25c)]=!0x1,_0x2308ef[_0x21a244(0x4da)]=0x0,_0x2308ef[_0x21a244(0x276)]=_0x21a244(0x254)+_0x21a244(0x1f3)+_0x21a244(0x2c4);if(!_0x109aee)return _0x2308ef;let _0x540465;if(_0x13576f['YPUOh'](_0x21a244(0x289),typeof _0x24b3e9)){const _0x3fbfc6={};_0x3fbfc6[_0x21a244(0x25c)]=!0x1,_0x3fbfc6[_0x21a244(0x4da)]=0x0,_0x3fbfc6['feedback']=_0x21a244(0x4b9)+_0x21a244(0x3c6)+_0x21a244(0x310);if(!_0x24dfd9['isArray'](_0x55faef['options']))return _0x3fbfc6;{const _0x38b222=_0x1d92c3[_0x21a244(0x2db)][_0x543f81];_0x540465=_0x13576f[_0x21a244(0x32b)](_0x21a244(0x4aa),typeof _0x38b222)?_0x38b222:_0x13576f[_0x21a244(0x2ff)](_0x41e95d,_0x38b222&&_0x13576f[_0x21a244(0x233)]('object',typeof _0x38b222)&&_0x13576f[_0x21a244(0x3f9)](_0x13576f[_0x21a244(0x362)],_0x38b222)?_0x38b222[_0x21a244(0x38e)]??'':_0x38b222??'');}}else _0x540465=_0x13576f[_0x21a244(0x2ff)](_0x409187,_0xbb3b81&&_0x13576f['RpIpe']==typeof _0x224abe&&_0x13576f[_0x21a244(0x3f9)](_0x13576f[_0x21a244(0x362)],_0x2847eb)?_0x4b5eea['text']??'':_0x13576f[_0x21a244(0x308)](_0x230bee,''));const _0x1cb9ef=_0x540465['toLowerCas'+'e']()['trim']()===_0x109aee[_0x21a244(0x357)+'e']()['trim'](),_0x317b61={};return _0x317b61[_0x21a244(0x25c)]=_0x1cb9ef,_0x317b61['score']=_0x1cb9ef?0x1:0x0,_0x317b61[_0x21a244(0x276)]=_0x1cb9ef?_0x21a244(0x359)+'\x20\x22'+_0x540465+(_0x21a244(0x32d)+_0x21a244(0x36c))+_0x109aee+'\x22':_0x21a244(0x3d3)+_0x21a244(0x29c)+_0x540465+('\x22\x20but\x20corr'+_0x21a244(0x299)+_0x21a244(0x2b2))+_0x109aee+'\x22',_0x317b61;}}return{'audio':_0x13576f['SGDis'](String,_0x13576f[_0x21a244(0x308)](_0x9111d2,''))};});_0x54d5f5(_0xceedaa);const _0x425612=_0xceedaa[_0x5138ce(0x3b9)](_0x12ab2f=>String(_0x12ab2f[_0x5138ce(0x4d9)]??'')),_0x3a62b8={};return _0x3a62b8['id']=_0x596dc3['id'],_0x3a62b8[_0x5138ce(0x49d)]=_0x596dc3['question'],_0x3a62b8[_0x5138ce(0x2db)]=_0xceedaa,_0x3a62b8[_0x5138ce(0x3ab)+_0x5138ce(0x28d)]=_0x425612,_0x3a62b8;});else{const _0x855d8c=(_0x14af38[_0x4a269b(0x2db)]||[])[_0x4a269b(0x3b9)](_0x281326=>'string'==typeof _0x281326?{'text':_0x281326}:_0x281326&&'object'==typeof _0x281326?{'text':_0x52cdda(_0x281326['text']??'')}:{'text':_0x1ac361(_0x281326??'')});_0x27300e[_0x4a269b(0x469)](_0x552fe7,_0x855d8c);const _0xa58497=_0x855d8c[_0x4a269b(0x3b9)](_0x3963a8=>_0x8081f6(_0x3963a8[_0x4a269b(0x38e)]??'')),_0x5ae6f9={};return _0x5ae6f9['id']=_0x583b8b['id'],_0x5ae6f9[_0x4a269b(0x49d)]=_0x43651f[_0x4a269b(0x49d)],_0x5ae6f9[_0x4a269b(0x2db)]=_0x855d8c,_0x5ae6f9[_0x4a269b(0x3ab)+_0x4a269b(0x28d)]=_0xa58497,_0x5ae6f9;}}(_0x561249);case _0x24a5c7[_0x459c89(0x328)]:return function(_0x16f0db){const _0xf58de4=_0x459c89,_0x13f58a={'dbwye':function(_0x23ad7d,_0xb9488c){const _0x4b81b2=a0_0x3575;return _0x27300e[_0x4b81b2(0x335)](_0x23ad7d,_0xb9488c);},'npehd':_0xf58de4(0x291)};return _0x16f0db[_0xf58de4(0x3b9)](_0x28dd25=>{const _0x2891b2=_0xf58de4;if(_0x13f58a[_0x2891b2(0x380)](_0x2891b2(0x238),_0x13f58a['npehd'])){const _0x7abcdc=(_0x28dd25[_0x2891b2(0x2db)]||[])[_0x2891b2(0x3b9)](_0x19bf64=>_0x2891b2(0x4aa)==typeof _0x19bf64?{'text':_0x19bf64}:_0x19bf64&&_0x2891b2(0x2d2)==typeof _0x19bf64?{'text':String(_0x19bf64[_0x2891b2(0x38e)]??'')}:{'text':String(_0x19bf64??'')});_0x54d5f5(_0x7abcdc);const _0x1436f3=_0x7abcdc[_0x2891b2(0x3b9)](_0x3c85cc=>String(_0x3c85cc[_0x2891b2(0x38e)]??'')),_0x818949={};return _0x818949['id']=_0x28dd25['id'],_0x818949[_0x2891b2(0x37f)]=_0x28dd25[_0x2891b2(0x37f)],_0x818949[_0x2891b2(0x49d)]=_0x28dd25[_0x2891b2(0x49d)],_0x818949[_0x2891b2(0x2db)]=_0x7abcdc,_0x818949[_0x2891b2(0x3ab)+'Options']=_0x1436f3,_0x818949;}else{const _0x3b4e7d={'awysT':function(_0x24b355,_0x171b31){return _0x24b355(_0x171b31);}};return _0x5bf1e7[_0x2891b2(0x3b9)](_0x1bd06b=>{const _0x560986=_0x2891b2,_0x3b0d87=(_0x1bd06b[_0x560986(0x2db)]||[])[_0x560986(0x3b9)](_0x2d6357=>_0x560986(0x4aa)==typeof _0x2d6357?{'text':_0x2d6357}:_0x2d6357&&'object'==typeof _0x2d6357?{'text':_0x2a63ee(_0x2d6357[_0x560986(0x38e)]??'')}:{'text':_0x4ef808(_0x2d6357??'')});_0x3b4e7d[_0x560986(0x38b)](_0xd1f734,_0x3b0d87);const _0x36b691=_0x3b0d87[_0x560986(0x3b9)](_0x31f00d=>_0x2d6c21(_0x31f00d[_0x560986(0x38e)]??'')),_0xb8c24={};return _0xb8c24['id']=_0x1bd06b['id'],_0xb8c24[_0x560986(0x49d)]=_0x1bd06b[_0x560986(0x4d9)]||_0x1bd06b[_0x560986(0x3a0)],_0xb8c24['options']=_0x3b0d87,_0xb8c24['__shuffled'+_0x560986(0x28d)]=_0x36b691,_0xb8c24;});}});}(_0x561249);case _0x24a5c7[_0x459c89(0x331)]:return function(_0x500ddf){const _0x1f2006=_0x459c89,_0xa58be={'NoKZv':function(_0x3a85d2,_0x22175a){return _0x3a85d2/_0x22175a;},'rktKM':function(_0x54267a,_0x285f1c){return _0x25ed87['ACPkY'](_0x54267a,_0x285f1c);},'HmhRM':function(_0x4dd68b,_0x8ee38d){return _0x25ed87['Qcjtu'](_0x4dd68b,_0x8ee38d);},'hQxlV':_0x25ed87[_0x1f2006(0x30f)],'LCPXz':_0x25ed87[_0x1f2006(0x4a0)],'aiWkc':function(_0x4a5310,_0x45e7b1){const _0x27c530=_0x1f2006;return _0x25ed87[_0x27c530(0x36e)](_0x4a5310,_0x45e7b1);},'adZpG':_0x25ed87[_0x1f2006(0x427)],'IZKye':function(_0x448740,_0x401f8f){return _0x448740(_0x401f8f);},'cpotw':function(_0xa69957,_0x28fee5){const _0x58e40a=_0x1f2006;return _0x25ed87[_0x58e40a(0x369)](_0xa69957,_0x28fee5);},'KOzTy':function(_0x53b321,_0x1a07e9){return _0x25ed87['hdJZR'](_0x53b321,_0x1a07e9);}};if(_0x25ed87[_0x1f2006(0x2a3)]('wmYdb',_0x1f2006(0x3bf))){const _0x291461={};_0x291461[_0x1f2006(0x4ce)]=_0x3842d4,_0x291461[_0x1f2006(0x225)]=_0x2918b7,(this['sendToPare'+'nt'](_0x42011d['SDK_MESSAG'+_0x1f2006(0x483)][_0x1f2006(0x3ee)],_0x291461,_0x29925c),this[_0x1f2006(0x36a)](_0x1f2006(0x440),_0x1f2006(0x1eb)+_0x2d3598+'\x20-\x20'+_0x17cdba));}else return _0x500ddf[_0x1f2006(0x3b9)](_0x2d1328=>{const _0x1dd642=_0x1f2006,_0x12199b=(_0x2d1328[_0x1dd642(0x2db)]||[])[_0x1dd642(0x3b9)](_0x21dc3d=>{const _0x3b6305=_0x1dd642,_0x32b060={'qcXZt':function(_0x7303fa,_0x3991c){const _0x266288=a0_0x3575;return _0xa58be[_0x266288(0x2da)](_0x7303fa,_0x3991c);},'ClJpY':function(_0x55046f,_0x577a2b){return _0xa58be['rktKM'](_0x55046f,_0x577a2b);}};if(_0xa58be[_0x3b6305(0x472)](_0xa58be[_0x3b6305(0x293)],typeof _0x21dc3d))return{'image_url':_0x21dc3d};if(_0x21dc3d&&_0xa58be[_0x3b6305(0x4ae)]==typeof _0x21dc3d){if(_0xa58be[_0x3b6305(0x361)](_0x3b6305(0x4d2),_0xa58be[_0x3b6305(0x20b)])){const _0x266248=_0x5cf22b['from'](this['userAnswer'+'s']['values']())[_0x3b6305(0x3b9)](_0x493c3b=>({'question_id':_0x493c3b[_0x3b6305(0x2cd)+'d'],'choice':_0x493c3b[_0x3b6305(0x1e9)],'correct':_0x493c3b[_0x3b6305(0x2b4)],'synced':_0x493c3b[_0x3b6305(0x4bc)],'time_spent':_0x493c3b[_0x3b6305(0x29d)]})),_0x6d8b47=_0x266248[_0x3b6305(0x257)](_0x4bac2a=>_0x4bac2a['correct'])[_0x3b6305(0x24e)],_0x47c070=this[_0x3b6305(0x1fa)+_0x3b6305(0x3f5)][_0x3b6305(0x475)],_0x3f5068=_0x266248[_0x3b6305(0x1f4)](_0x241ee9=>_0x241ee9[_0x3b6305(0x4bc)]);this[_0x3b6305(0x4a1)+'nt'](_0x20b586[_0x3b6305(0x3ce)+'E_TYPES'][_0x3b6305(0x441)+_0x3b6305(0x30e)],{'score':_0x47c070>0x0?_0x29fbc5[_0x3b6305(0x40f)](_0x32b060[_0x3b6305(0x23a)](_0x6d8b47,_0x47c070)*0x64):0x0,'total':_0x47c070,'correct':_0x6d8b47,'wrong':_0x32b060['ClJpY'](_0x47c070,_0x6d8b47),'synced':_0x3f5068,'details':_0x266248},_0x2d20b2);}else{const _0x35f26a=_0x21dc3d[_0x3b6305(0x37f)]||_0x21dc3d[_0x3b6305(0x3e5)]||'';return{'image_url':String(_0x35f26a)};}}return{'image_url':_0xa58be[_0x3b6305(0x273)](String,_0xa58be['cpotw'](_0x21dc3d,''))};});_0xa58be[_0x1dd642(0x249)](_0x54d5f5,_0x12199b);const _0x54b551=_0x12199b[_0x1dd642(0x3b9)](_0xf5b5f9=>String(_0xf5b5f9[_0x1dd642(0x37f)]??'')),_0x1372f2={};return _0x1372f2['id']=_0x2d1328['id'],_0x1372f2[_0x1dd642(0x49d)]=_0x2d1328[_0x1dd642(0x49d)],_0x1372f2['options']=_0x12199b,_0x1372f2[_0x1dd642(0x3ab)+_0x1dd642(0x28d)]=_0x54b551,_0x1372f2;});}(_0x561249);case _0x459c89(0x20f):case _0x24a5c7['mcVmC']:case _0x24a5c7[_0x459c89(0x3bb)]:case _0x24a5c7[_0x459c89(0x2a9)]:return function(_0x3201e8){const _0x27e73a=_0x459c89,_0x236018={'hRcCg':function(_0x5834fe,_0x18ba54){return _0x5834fe==_0x18ba54;},'GkjhN':function(_0x557826,_0x5d04ee){return _0x27300e['aeuwQ'](_0x557826,_0x5d04ee);},'Pxpgf':function(_0x5e944f,_0x5e9dc6){return _0x5e944f!==_0x5e9dc6;},'tCBlS':_0x27300e[_0x27e73a(0x433)],'wulEQ':_0x27300e['vnpin'],'bPxvn':function(_0x3c3b4a,_0x2dc770){const _0xab7d8c=_0x27e73a;return _0x27300e[_0xab7d8c(0x2c9)](_0x3c3b4a,_0x2dc770);},'TfQoc':function(_0xe507a5,_0x467dba){const _0x21e36b=_0x27e73a;return _0x27300e[_0x21e36b(0x329)](_0xe507a5,_0x467dba);},'kmsIE':function(_0x3a00ae,_0xc715c6){const _0x160bf4=_0x27e73a;return _0x27300e[_0x160bf4(0x389)](_0x3a00ae,_0xc715c6);},'UmexU':_0x27300e[_0x27e73a(0x493)],'QxCpi':_0x27e73a(0x26f)+_0x27e73a(0x251)+_0x27e73a(0x298)};if(_0x27300e['PBfTY'](_0x27300e[_0x27e73a(0x3dd)],_0x27300e[_0x27e73a(0x3dd)]))return _0x3201e8[_0x27e73a(0x3b9)](_0x30bae3=>{const _0x17bfaa=_0x27e73a,_0x1fb019={'wjNIS':function(_0x1ecdeb,_0x40c54f){const _0x5b279d=a0_0x3575;return _0x236018[_0x5b279d(0x4c8)](_0x1ecdeb,_0x40c54f);},'ugLWZ':function(_0x1d946a,_0x2f757f){const _0x1f9e33=a0_0x3575;return _0x236018[_0x1f9e33(0x364)](_0x1d946a,_0x2f757f);},'DqOnY':function(_0x38442f,_0x1427a3){return _0x38442f(_0x1427a3);}};if(_0x236018[_0x17bfaa(0x4cc)](_0x236018['tCBlS'],_0x236018[_0x17bfaa(0x394)])){const _0xc59c54=_0x30bae3['answer']||_0x30bae3[_0x17bfaa(0x27c)]||[],_0x167998=_0x30bae3['missing_le'+_0x17bfaa(0x409)]||0x0;if(0x0===_0x167998||_0x236018[_0x17bfaa(0x426)](0x0,_0xc59c54[_0x17bfaa(0x24e)]))return{'id':_0x30bae3['id'],'question':[..._0xc59c54],'options':[],..._0x30bae3[_0x17bfaa(0x3a0)]&&{'audio_url':_0x30bae3['audio_url']}};const _0x29d71a={};_0x29d71a[_0x17bfaa(0x24e)]=_0xc59c54[_0x17bfaa(0x24e)];const _0x4a0d57=Array[_0x17bfaa(0x443)](_0x29d71a,(_0x20b0b9,_0x1c4199)=>_0x1c4199),_0x23f3a5=new Set(),_0x11d8b9=Math[_0x17bfaa(0x1f8)](_0x167998,_0xc59c54[_0x17bfaa(0x24e)]);for(;_0x236018[_0x17bfaa(0x4a4)](_0x23f3a5[_0x17bfaa(0x475)],_0x11d8b9);){const _0x2f4289=Math['floor'](_0x236018[_0x17bfaa(0x267)](Math['random'](),_0x4a0d57[_0x17bfaa(0x24e)])),_0x22a67c=_0x4a0d57[_0x2f4289];_0x23f3a5[_0x17bfaa(0x458)](_0x22a67c),_0x4a0d57[_0x17bfaa(0x468)](_0x2f4289,0x1);}const _0xfee21e=_0xc59c54['map']((_0x23ba59,_0x1d8155)=>_0x23f3a5[_0x17bfaa(0x391)](_0x1d8155)?'':String(_0x23ba59)),_0x523e36=Array[_0x17bfaa(0x443)](_0x23f3a5)[_0x17bfaa(0x3b9)](_0x2dbc26=>String(_0xc59c54[_0x2dbc26]));_0x54d5f5(_0x523e36);const _0x478722={};_0x478722['id']=_0x30bae3['id'],_0x478722[_0x17bfaa(0x49d)]=_0xfee21e,_0x478722[_0x17bfaa(0x2db)]=_0x523e36,_0x478722[_0x17bfaa(0x3ab)+_0x17bfaa(0x28d)]=[..._0x523e36];const _0x37ddfb=_0x478722;return _0x30bae3[_0x17bfaa(0x3a0)]&&(_0x37ddfb[_0x17bfaa(0x3a0)]=_0x30bae3[_0x17bfaa(0x3a0)]),_0x37ddfb;}else{const _0x2baaa0={'ktdee':function(_0x5e014a,_0x58b307){return _0x1fb019['wjNIS'](_0x5e014a,_0x58b307);},'czoxH':_0x17bfaa(0x4aa),'xegGG':function(_0x32acb6,_0x30b77f){return _0x1fb019['ugLWZ'](_0x32acb6,_0x30b77f);}},_0x4e1cf0=(_0x498844[_0x17bfaa(0x2db)]||[])[_0x17bfaa(0x3b9)](_0x6fdb1a=>{const _0xde3b5c=_0x17bfaa;if(_0x2baaa0[_0xde3b5c(0x229)](_0x2baaa0[_0xde3b5c(0x48d)],typeof _0x6fdb1a))return{'audio':_0x6fdb1a};if(_0x6fdb1a&&_0xde3b5c(0x2d2)==typeof _0x6fdb1a){const _0x4c7d56=_0x6fdb1a[_0xde3b5c(0x4d9)]||_0x6fdb1a[_0xde3b5c(0x3a0)]||'';return{'audio':_0x41fe0c(_0x4c7d56)};}return{'audio':_0x1412ca(_0x2baaa0[_0xde3b5c(0x3d5)](_0x6fdb1a,''))};});_0x1fb019[_0x17bfaa(0x313)](_0x2e661c,_0x4e1cf0);const _0x4a960b=_0x4e1cf0[_0x17bfaa(0x3b9)](_0x4dfb1b=>_0x1ead62(_0x4dfb1b[_0x17bfaa(0x4d9)]??'')),_0x1a91b5={};return _0x1a91b5['id']=_0xdfb1ce['id'],_0x1a91b5['question']=_0x5dbb60[_0x17bfaa(0x49d)],_0x1a91b5[_0x17bfaa(0x2db)]=_0x4e1cf0,_0x1a91b5[_0x17bfaa(0x3ab)+'Options']=_0x4a960b,_0x1a91b5;}});else{const _0x47f94f={};_0x47f94f[_0x27e73a(0x336)]=_0x46f64d['debug']??!0x1,_0x47f94f[_0x27e73a(0x248)+_0x27e73a(0x1d7)]=_0x2ab769['allowedOri'+_0x27e73a(0x1d7)]??['*'],(this[_0x27e73a(0x465)+_0x27e73a(0x42d)]=null,this[_0x27e73a(0x2cc)]=null,this[_0x27e73a(0x3eb)]=null,this[_0x27e73a(0x2f2)+'Id']=null,this[_0x27e73a(0x31a)]=null,this['apiBaseUrl']='',this[_0x27e73a(0x234)]='',this['originalIt'+_0x27e73a(0x3f5)]=new _0x250c59(),this['clientItem'+'s']=new _0x598240(),this['sanitizedI'+_0x27e73a(0x26c)]=[],this['userAnswer'+'s']=new _0x5390c6(),this[_0x27e73a(0x2cf)+_0x27e73a(0x3c2)]=new _0x5cc303(),this[_0x27e73a(0x48e)+'zed']=!0x1,this[_0x27e73a(0x471)+'in']=null,this[_0x27e73a(0x2b3)]=_0x47f94f,this['setupMessa'+_0x27e73a(0x22a)](),this[_0x27e73a(0x36a)](_0x236018[_0x27e73a(0x277)],_0x236018['QxCpi']));}}(_0x561249);case _0x24a5c7[_0x459c89(0x4d8)]:case'G121':case _0x459c89(0x404):case _0x24a5c7[_0x459c89(0x29b)]:return function(_0x3e57da){const _0x5e7529=_0x459c89;return _0x3e57da[_0x5e7529(0x3b9)](_0x38f35d=>{const _0x14d504=_0x5e7529,_0x16a271=_0x38f35d[_0x14d504(0x3f0)]||_0x38f35d[_0x14d504(0x27c)]||[],_0x565884=_0x38f35d['missing_le'+_0x14d504(0x409)]||0x0;if(_0x27300e['PBfTY'](0x0,_0x565884)||_0x27300e['vVrsI'](0x0,_0x16a271[_0x14d504(0x24e)]))return{'id':_0x38f35d['id'],'question':[..._0x16a271],'options':[],..._0x38f35d[_0x14d504(0x3a0)]&&{'audio_url':_0x38f35d[_0x14d504(0x3a0)]}};const _0x59eca2={};_0x59eca2[_0x14d504(0x24e)]=_0x16a271[_0x14d504(0x24e)];const _0x4fdeee=Array[_0x14d504(0x443)](_0x59eca2,(_0x437ac3,_0x51705a)=>_0x51705a),_0x5197a4=new Set(),_0x2ef2a1=Math['min'](_0x565884,_0x16a271['length']);for(;_0x27300e['nskYB'](_0x5197a4[_0x14d504(0x475)],_0x2ef2a1);){const _0x3c1540=Math['floor'](_0x27300e[_0x14d504(0x389)](Math[_0x14d504(0x1d8)](),_0x4fdeee[_0x14d504(0x24e)])),_0x10d262=_0x4fdeee[_0x3c1540];_0x5197a4[_0x14d504(0x458)](_0x10d262),_0x4fdeee[_0x14d504(0x468)](_0x3c1540,0x1);}const _0xf0f74b=_0x16a271['map']((_0x5b0a5b,_0x1db80e)=>_0x5197a4[_0x14d504(0x391)](_0x1db80e)?'':String(_0x5b0a5b)),_0x32a126=Array['from'](_0x5197a4)[_0x14d504(0x3b9)](_0x2be66a=>String(_0x16a271[_0x2be66a]));_0x54d5f5(_0x32a126);const _0x117b64={};_0x117b64['id']=_0x38f35d['id'],_0x117b64[_0x14d504(0x49d)]=_0xf0f74b,_0x117b64['options']=_0x32a126,_0x117b64[_0x14d504(0x3ab)+_0x14d504(0x28d)]=[..._0x32a126];const _0x575894=_0x117b64;return _0x38f35d[_0x14d504(0x3a0)]&&(_0x575894[_0x14d504(0x3a0)]=_0x38f35d[_0x14d504(0x3a0)]),_0x575894;});}(_0x561249);default:return console[_0x459c89(0x3e9)](_0x459c89(0x367)+_0x459c89(0x413)+_0x459c89(0x466)+'\x20code:\x20'+_0x5bc12f+(',\x20returnin'+_0x459c89(0x393))),_0x561249;}},_0x1b7dc6[_0x1f5be5(0x297)+'r']=function(_0x481bac,_0x584709,_0x44259c){const _0x5bb682=_0x1f5be5,_0x17f4d6={'WlfKV':function(_0xa1fbeb,_0x4e5332){const _0x4ea393=a0_0x3575;return _0x25ed87[_0x4ea393(0x205)](_0xa1fbeb,_0x4e5332);},'wjmdo':_0x25ed87[_0x5bb682(0x2bd)],'xIlrv':function(_0x59aa71,_0x4bbf4e){const _0x21d398=_0x5bb682;return _0x25ed87[_0x21d398(0x3e0)](_0x59aa71,_0x4bbf4e);},'rtGLo':_0x25ed87[_0x5bb682(0x4a9)],'DHBXe':_0x5bb682(0x4aa),'ZDFDn':function(_0x443501,_0x12334a){return _0x25ed87['YpSNP'](_0x443501,_0x12334a);},'TMztL':_0x25ed87[_0x5bb682(0x4a0)],'IEKtL':_0x25ed87['amOBF'],'YNQqF':function(_0x4f59d2,_0x2f0667){const _0x8d8ef=_0x5bb682;return _0x25ed87[_0x8d8ef(0x369)](_0x4f59d2,_0x2f0667);},'jFyUP':function(_0x210bfd,_0x116375){const _0x2bbd0e=_0x5bb682;return _0x25ed87[_0x2bbd0e(0x2f6)](_0x210bfd,_0x116375);},'VooWD':function(_0x400616,_0x4eb492){const _0x560f4a=_0x5bb682;return _0x25ed87[_0x560f4a(0x369)](_0x400616,_0x4eb492);},'SkQsD':function(_0x94f6c2,_0x4d02b1){return _0x94f6c2===_0x4d02b1;},'Ynijd':function(_0x1c3d42,_0x1bef61){const _0x3f988d=_0x5bb682;return _0x25ed87[_0x3f988d(0x2a3)](_0x1c3d42,_0x1bef61);}};switch(_0x481bac){case _0x25ed87['CKmsb']:case _0x25ed87[_0x5bb682(0x330)]:case _0x25ed87[_0x5bb682(0x439)]:case _0x5bb682(0x266):case _0x5bb682(0x3ac):return function(_0x24c027,_0x337343){const _0x393f55=_0x5bb682,_0x59129f=_0x17f4d6['WlfKV'](String,_0x24c027['answer']||''),_0x5e9dcf={};_0x5e9dcf['isCorrect']=!0x1,_0x5e9dcf[_0x393f55(0x4da)]=0x0,_0x5e9dcf[_0x393f55(0x276)]=_0x17f4d6[_0x393f55(0x1dd)];if(!_0x59129f)return _0x5e9dcf;let _0x2a241a;if(_0x17f4d6['xIlrv'](_0x17f4d6[_0x393f55(0x1df)],typeof _0x337343)){const _0xd88055={};_0xd88055[_0x393f55(0x25c)]=!0x1,_0xd88055[_0x393f55(0x4da)]=0x0,_0xd88055['feedback']=_0x393f55(0x4b9)+_0x393f55(0x3c6)+_0x393f55(0x310);if(!Array[_0x393f55(0x2f9)](_0x24c027[_0x393f55(0x2db)]))return _0xd88055;{const _0x5dc47b=_0x24c027['options'][_0x337343];_0x2a241a=_0x17f4d6[_0x393f55(0x1e4)](_0x17f4d6[_0x393f55(0x334)],typeof _0x5dc47b)?_0x5dc47b:_0x17f4d6[_0x393f55(0x4ea)](String,_0x5dc47b&&_0x17f4d6[_0x393f55(0x2dd)](_0x17f4d6[_0x393f55(0x22b)],typeof _0x5dc47b)&&_0x17f4d6[_0x393f55(0x3de)]in _0x5dc47b?_0x5dc47b[_0x393f55(0x38e)]??'':_0x17f4d6[_0x393f55(0x286)](_0x5dc47b,''));}}else _0x2a241a=String(_0x337343&&_0x17f4d6['jFyUP'](_0x393f55(0x2d2),typeof _0x337343)&&_0x17f4d6[_0x393f55(0x3de)]in _0x337343?_0x337343[_0x393f55(0x38e)]??'':_0x17f4d6[_0x393f55(0x365)](_0x337343,''));const _0x2c4f64=_0x2a241a[_0x393f55(0x357)+'e']()[_0x393f55(0x2c6)]()===_0x59129f[_0x393f55(0x357)+'e']()[_0x393f55(0x2c6)](),_0x29c118={};return _0x29c118[_0x393f55(0x25c)]=_0x2c4f64,_0x29c118[_0x393f55(0x4da)]=_0x2c4f64?0x1:0x0,_0x29c118[_0x393f55(0x276)]=_0x2c4f64?'✅\x20Correct!'+'\x20\x22'+_0x2a241a+(_0x393f55(0x32d)+'answer\x20\x22')+_0x59129f+'\x22':_0x393f55(0x3d3)+_0x393f55(0x29c)+_0x2a241a+('\x22\x20but\x20corr'+'ect\x20answer'+_0x393f55(0x2b2))+_0x59129f+'\x22',_0x29c118;}(_0x584709,_0x44259c);case _0x25ed87[_0x5bb682(0x38f)]:case _0x25ed87[_0x5bb682(0x489)]:case _0x5bb682(0x250):case _0x25ed87[_0x5bb682(0x432)]:case _0x25ed87[_0x5bb682(0x2c8)]:case _0x25ed87[_0x5bb682(0x34b)]:case _0x25ed87[_0x5bb682(0x38d)]:case _0x25ed87[_0x5bb682(0x4e4)]:return function(_0x4b300a,_0x1ed474){const _0x1552f3=_0x5bb682;if(_0x17f4d6[_0x1552f3(0x32c)](_0x1552f3(0x2fd),_0x1552f3(0x2fd))){const _0x11ec47=_0x4b300a[_0x1552f3(0x3f0)]||_0x4b300a[_0x1552f3(0x27c)],_0x417f17={};_0x417f17[_0x1552f3(0x25c)]=!0x1,_0x417f17[_0x1552f3(0x4da)]=0x0;if(!Array[_0x1552f3(0x2f9)](_0x1ed474)||!Array['isArray'](_0x11ec47))return _0x417f17;const _0x11e250=(_0x1df4a8=_0x11ec47,_0x17f4d6[_0x1552f3(0x45a)]((_0x3f7ff0=_0x1ed474)[_0x1552f3(0x24e)],_0x1df4a8['length'])&&_0x3f7ff0[_0x1552f3(0x1f4)]((_0x32226f,_0x4083d9)=>_0x1552f3(0x4aa)==typeof _0x32226f&&_0x1552f3(0x4aa)==typeof _0x1df4a8[_0x4083d9]?_0x32226f[_0x1552f3(0x357)+'e']()[_0x1552f3(0x2c6)]()===_0x1df4a8[_0x4083d9]['toLowerCas'+'e']()['trim']():_0x32226f===_0x1df4a8[_0x4083d9]));var _0x3f7ff0,_0x1df4a8;const _0x4c0aae={};return _0x4c0aae[_0x1552f3(0x25c)]=_0x11e250,_0x4c0aae[_0x1552f3(0x4da)]=_0x11e250?0x1:0x0,_0x4c0aae;}else _0x1a8151['id']&&this['clientItem'+'s'][_0x1552f3(0x34e)](_0x15c6c5['id'],_0x3aa3b9);}(_0x584709,_0x44259c);default:const _0xb6ad46={};_0xb6ad46[_0x5bb682(0x25c)]=!0x1,_0xb6ad46[_0x5bb682(0x4da)]=0x0;return console[_0x5bb682(0x3e9)](_0x5bb682(0x367)+_0x5bb682(0x413)+_0x5bb682(0x466)+'\x20code\x20for\x20'+'scoring:\x20'+_0x481bac),_0xb6ad46;}},_0x1b7dc6['GAME_CODES']={'G001':{'name':_0x24a5c7[_0x1f5be5(0x420)],'category':_0x1f5be5(0x4a6),'hasAudio':!0x1,'hasImage':!0x1},'G002':{'name':_0x24a5c7[_0x1f5be5(0x314)],'category':'quiz','hasAudio':!0x0,'hasImage':!0x1},'G003':{'name':_0x24a5c7[_0x1f5be5(0x1ed)],'category':_0x24a5c7[_0x1f5be5(0x3da)],'hasAudio':!0x0,'hasImage':!0x1},'G004':{'name':_0x24a5c7['wAgmR'],'category':_0x24a5c7[_0x1f5be5(0x3da)],'hasAudio':!0x1,'hasImage':!0x0},'G005':{'name':_0x24a5c7['HeFjB'],'category':_0x24a5c7[_0x1f5be5(0x3da)],'hasAudio':!0x1,'hasImage':!0x0},'G110':{'name':_0x24a5c7[_0x1f5be5(0x491)],'category':_0x24a5c7[_0x1f5be5(0x3bc)],'hasAudio':!0x1},'G111':{'name':_0x1f5be5(0x342)+_0x1f5be5(0x281),'category':_0x24a5c7[_0x1f5be5(0x3bc)],'hasAudio':!0x0},'G112':{'name':_0x1f5be5(0x342)+'ord\x20Audio','category':_0x24a5c7['viuic'],'hasAudio':!0x0},'G113':_0x42afe4,'G120':{'name':_0x24a5c7[_0x1f5be5(0x3bd)],'category':_0x1f5be5(0x412)+_0x1f5be5(0x371),'hasAudio':!0x1},'G121':{'name':_0x24a5c7[_0x1f5be5(0x2f1)],'category':_0x24a5c7[_0x1f5be5(0x4a3)],'hasAudio':!0x0},'G122':{'name':_0x24a5c7[_0x1f5be5(0x2f1)],'category':_0x24a5c7[_0x1f5be5(0x4a3)],'hasAudio':!0x0},'G123':{'name':_0x24a5c7[_0x1f5be5(0x2f1)],'category':_0x1f5be5(0x412)+'entence','hasAudio':!0x0}});}},0xb9(_0x5c3860,_0x559ab7,_0x5dcb09){const _0x3b60da=_0x41c3f4,_0x58db97={'LxeBo':function(_0x1342ff,_0x55e145){return _0x24a5c7['HiVLV'](_0x1342ff,_0x55e145);},'xQzBc':function(_0x417783,_0x24f189){const _0x1f4a49=a0_0x3575;return _0x24a5c7[_0x1f4a49(0x42e)](_0x417783,_0x24f189);},'GVFLv':function(_0x4d79f4,_0x41e619){const _0x308c3f=a0_0x3575;return _0x24a5c7[_0x308c3f(0x495)](_0x4d79f4,_0x41e619);},'YNIBw':function(_0x44c42e,_0x29ba24){const _0x5ea4c0=a0_0x3575;return _0x24a5c7[_0x5ea4c0(0x3df)](_0x44c42e,_0x29ba24);},'KXVIT':_0x3b60da(0x454),'WlCtI':_0x3b60da(0x212),'OpERR':_0x24a5c7[_0x3b60da(0x4bb)],'EnUUW':_0x3b60da(0x3e9),'SpwIg':_0x24a5c7[_0x3b60da(0x39d)],'wCRUz':_0x24a5c7['SmnfR'],'mlnCu':function(_0x1f4c1a,_0x16eb37){const _0x405075=_0x3b60da;return _0x24a5c7[_0x405075(0x3ca)](_0x1f4c1a,_0x16eb37);},'ZdmvF':_0x24a5c7[_0x3b60da(0x4ba)],'UXDns':'oLZUH','NXqLi':_0x3b60da(0x377)+_0x3b60da(0x317),'ymKiI':_0x24a5c7['fVEte'],'lzcQY':_0x3b60da(0x1e0),'dexyG':_0x24a5c7[_0x3b60da(0x33c)],'ZsBBo':_0x24a5c7['dFaWp'],'uuMpU':_0x24a5c7[_0x3b60da(0x2ca)],'JTvBB':_0x24a5c7['csTex'],'SBNeW':_0x24a5c7[_0x3b60da(0x2d0)],'LxZPf':function(_0x90e15d,_0x1eb334){const _0x3f7367=_0x3b60da;return _0x24a5c7[_0x3f7367(0x4dd)](_0x90e15d,_0x1eb334);},'qoRIS':_0x24a5c7[_0x3b60da(0x231)],'BAGxb':function(_0x28bfb7,_0x30b9dc){return _0x28bfb7(_0x30b9dc);},'VRmVt':function(_0x232789,_0x23102a){const _0x369f4a=_0x3b60da;return _0x24a5c7[_0x369f4a(0x241)](_0x232789,_0x23102a);},'YEtSH':_0x24a5c7['VlClK'],'Utxrz':_0x24a5c7['VXDqH'],'FNSWU':_0x24a5c7[_0x3b60da(0x3f3)],'yFbmY':function(_0x1d266f,_0x3c9233){const _0x4873d5=_0x3b60da;return _0x24a5c7[_0x4873d5(0x3b2)](_0x1d266f,_0x3c9233);},'RLTby':function(_0x4baf5d,_0x6b58e5){const _0x1f7824=_0x3b60da;return _0x24a5c7[_0x1f7824(0x1dc)](_0x4baf5d,_0x6b58e5);},'qjRdt':function(_0x48e4a1,_0x255298){const _0x2bc6fc=_0x3b60da;return _0x24a5c7[_0x2bc6fc(0x42e)](_0x48e4a1,_0x255298);},'ojBQJ':function(_0x5330a4,_0x56749f){const _0x1321b9=_0x3b60da;return _0x24a5c7[_0x1321b9(0x261)](_0x5330a4,_0x56749f);},'ItlBX':_0x3b60da(0x2b7)+']','abTGc':function(_0x1726c9,_0x1ce09f){return _0x24a5c7['lYBCT'](_0x1726c9,_0x1ce09f);},'MRjJc':function(_0x170abd,_0xe75d42){const _0x4df7ba=_0x3b60da;return _0x24a5c7[_0x4df7ba(0x319)](_0x170abd,_0xe75d42);},'MHgxN':_0x24a5c7[_0x3b60da(0x4bd)],'JyuLJ':_0x24a5c7[_0x3b60da(0x405)],'MhEhx':_0x24a5c7[_0x3b60da(0x295)],'SyJVz':function(_0x35e22f,_0x40e160){const _0x389a6f=_0x3b60da;return _0x24a5c7[_0x389a6f(0x36f)](_0x35e22f,_0x40e160);},'hojSH':_0x24a5c7['GRWSJ'],'jBNtb':_0x24a5c7['bHwPj']};if(_0x24a5c7['TiSFf'](_0x3b60da(0x1fc),_0x24a5c7[_0x3b60da(0x4db)]))this[_0x3b60da(0x2d5)](_0x3b60da(0x264),_0x51d7c3[_0x3b60da(0x225)],_0x22b93b);else{const _0x4c0186={};_0x4c0186['value']=!0x0,(Object['defineProp'+_0x3b60da(0x41e)](_0x559ab7,'__esModule',_0x4c0186),_0x559ab7[_0x3b60da(0x1e3)+_0x3b60da(0x392)]=void 0x0);const _0x403c12=_0x24a5c7[_0x3b60da(0x4c5)](_0x5dcb09,0x95),_0x4ade6a=_0x5dcb09(0x2ba),_0x1c043b=_0x24a5c7[_0x3b60da(0x495)](_0x5dcb09,0x3c7);class _0x286974{constructor(_0x10cabe={}){const _0x5d286b=_0x3b60da,_0x1b17f2={'wxxHY':function(_0x291338,_0x4c1c36){return _0x291338===_0x4c1c36;},'XAqsl':function(_0x8dee40,_0x1926b1){const _0x3e5794=a0_0x3575;return _0x58db97[_0x3e5794(0x2d7)](_0x8dee40,_0x1926b1);},'zhkiI':function(_0x21c667,_0x3c54a3){const _0x2b573a=a0_0x3575;return _0x58db97[_0x2b573a(0x382)](_0x21c667,_0x3c54a3);},'bwLlM':function(_0x2fdf2f,_0x1cd4ab){const _0x23e8f4=a0_0x3575;return _0x58db97[_0x23e8f4(0x2d8)](_0x2fdf2f,_0x1cd4ab);}};if(_0x58db97[_0x5d286b(0x4dc)](_0x58db97['KXVIT'],_0x58db97[_0x5d286b(0x3a2)]))return _0xe5717b[_0x5d286b(0x3b9)](_0x9f374b=>{const _0x4c4bff=_0x5d286b,_0xf265fa=_0x9f374b[_0x4c4bff(0x3f0)]||_0x9f374b['parts']||[],_0x84eba=_0x9f374b['missing_le'+_0x4c4bff(0x409)]||0x0;if(_0x1b17f2[_0x4c4bff(0x402)](0x0,_0x84eba)||0x0===_0xf265fa['length'])return{'id':_0x9f374b['id'],'question':[..._0xf265fa],'options':[],..._0x9f374b[_0x4c4bff(0x3a0)]&&{'audio_url':_0x9f374b[_0x4c4bff(0x3a0)]}};const _0x1405dd={};_0x1405dd[_0x4c4bff(0x24e)]=_0xf265fa['length'];const _0x23b1f5=_0x71327[_0x4c4bff(0x443)](_0x1405dd,(_0xe122d,_0x5e7629)=>_0x5e7629),_0x29c192=new _0x4b5c2e(),_0x4be9ef=_0x1a8039[_0x4c4bff(0x1f8)](_0x84eba,_0xf265fa['length']);for(;_0x1b17f2['XAqsl'](_0x29c192[_0x4c4bff(0x475)],_0x4be9ef);){const _0x257bbd=_0x4d98ac[_0x4c4bff(0x2e9)](_0x1b17f2[_0x4c4bff(0x395)](_0x2d9848[_0x4c4bff(0x1d8)](),_0x23b1f5[_0x4c4bff(0x24e)])),_0x38a967=_0x23b1f5[_0x257bbd];_0x29c192[_0x4c4bff(0x458)](_0x38a967),_0x23b1f5[_0x4c4bff(0x468)](_0x257bbd,0x1);}const _0x20bb30=_0xf265fa['map']((_0x548dc1,_0x5136c5)=>_0x29c192['has'](_0x5136c5)?'':_0x4af3d7(_0x548dc1)),_0x54c1a5=_0x583117[_0x4c4bff(0x443)](_0x29c192)['map'](_0x425338=>_0x5af4e6(_0xf265fa[_0x425338]));_0x1b17f2[_0x4c4bff(0x45b)](_0x105d7,_0x54c1a5);const _0x5dc994={};_0x5dc994['id']=_0x9f374b['id'],_0x5dc994['question']=_0x20bb30,_0x5dc994['options']=_0x54c1a5,_0x5dc994[_0x4c4bff(0x3ab)+_0x4c4bff(0x28d)]=[..._0x54c1a5];const _0x32c768=_0x5dc994;return _0x9f374b[_0x4c4bff(0x3a0)]&&(_0x32c768[_0x4c4bff(0x3a0)]=_0x9f374b[_0x4c4bff(0x3a0)]),_0x32c768;});else{const _0x21a3da={};_0x21a3da[_0x5d286b(0x336)]=_0x10cabe['debug']??!0x1,_0x21a3da['allowedOri'+'gins']=_0x10cabe['allowedOri'+'gins']??['*'],(this['boundMessa'+_0x5d286b(0x42d)]=null,this[_0x5d286b(0x2cc)]=null,this['gameCode']=null,this['assignment'+'Id']=null,this[_0x5d286b(0x31a)]=null,this['apiBaseUrl']='',this[_0x5d286b(0x234)]='',this[_0x5d286b(0x1fa)+_0x5d286b(0x3f5)]=new Map(),this[_0x5d286b(0x275)+'s']=new Map(),this[_0x5d286b(0x358)+_0x5d286b(0x26c)]=[],this[_0x5d286b(0x1e6)+'s']=new Map(),this[_0x5d286b(0x2cf)+_0x5d286b(0x3c2)]=new Set(),this[_0x5d286b(0x48e)+_0x5d286b(0x338)]=!0x1,this['parentOrig'+'in']=null,this[_0x5d286b(0x2b3)]=_0x21a3da,this[_0x5d286b(0x27f)+'geListener'](),this[_0x5d286b(0x36a)](_0x58db97[_0x5d286b(0x271)],_0x58db97[_0x5d286b(0x4c6)]));}}[_0x3b60da(0x27f)+_0x3b60da(0x22a)](){const _0x450d64=_0x3b60da;this['boundMessa'+'geHandler']=this[_0x450d64(0x3f4)+_0x450d64(0x33e)][_0x450d64(0x415)](this),window['addEventLi'+_0x450d64(0x3ec)](_0x24a5c7[_0x450d64(0x24a)],this[_0x450d64(0x465)+_0x450d64(0x42d)]);}[_0x3b60da(0x3f4)+_0x3b60da(0x33e)](_0x318414){const _0x4167db=_0x3b60da;if(!this['isAllowedO'+'rigin'](_0x318414['origin']))return void this[_0x4167db(0x36a)](_0x58db97[_0x4167db(0x3e4)],_0x4167db(0x2a0)+_0x4167db(0x263)+_0x4167db(0x44f)+'zed\x20origin'+':\x20'+_0x318414[_0x4167db(0x3d6)]);const _0x1bc3bb=_0x318414[_0x4167db(0x3c5)];if((0x0,_0x1c043b['isSdkMessa'+'ge'])(_0x1bc3bb))switch(this[_0x4167db(0x36a)](_0x58db97['SpwIg'],_0x4167db(0x32e)+_0x1bc3bb[_0x4167db(0x307)],_0x1bc3bb[_0x4167db(0x490)]),this[_0x4167db(0x471)+'in']||(this[_0x4167db(0x471)+'in']=_0x318414[_0x4167db(0x3d6)]),_0x1bc3bb[_0x4167db(0x307)]){case _0x1c043b[_0x4167db(0x3ce)+_0x4167db(0x483)][_0x4167db(0x3c1)]:this[_0x4167db(0x2e3)](_0x1bc3bb[_0x4167db(0x490)],_0x1bc3bb[_0x4167db(0x292)]);break;case _0x1c043b['SDK_MESSAG'+_0x4167db(0x483)]['SDK_PUSH_D'+'ATA']:this[_0x4167db(0x388)+_0x4167db(0x430)](_0x1bc3bb[_0x4167db(0x490)],_0x1bc3bb[_0x4167db(0x292)]);break;case _0x1c043b['SDK_MESSAG'+_0x4167db(0x483)][_0x4167db(0x421)+_0x4167db(0x278)]:this['handleChec'+_0x4167db(0x375)](_0x1bc3bb[_0x4167db(0x490)],_0x1bc3bb[_0x4167db(0x292)]);break;case _0x1c043b[_0x4167db(0x3ce)+_0x4167db(0x483)][_0x4167db(0x22c)+_0x4167db(0x31f)]:this[_0x4167db(0x3e2)+_0x4167db(0x42c)](_0x1bc3bb[_0x4167db(0x292)]);break;case _0x1c043b['SDK_MESSAG'+_0x4167db(0x483)]['SDK_RETRY_'+'SYNC']:this['handleRetr'+_0x4167db(0x321)](_0x1bc3bb['payload'],_0x1bc3bb['request_id']);break;default:this['log'](_0x58db97[_0x4167db(0x3e4)],_0x4167db(0x341)+'ssage\x20type'+':\x20'+_0x1bc3bb[_0x4167db(0x307)]);}}['isAllowedO'+_0x3b60da(0x33b)](_0x1918da){const _0x227c31=_0x3b60da;return _0x58db97[_0x227c31(0x30a)]===_0x58db97[_0x227c31(0x30a)]?!!this[_0x227c31(0x2b3)][_0x227c31(0x248)+_0x227c31(0x1d7)]['includes']('*')||this[_0x227c31(0x2b3)][_0x227c31(0x248)+_0x227c31(0x1d7)][_0x227c31(0x216)](_0x1918da):_0x3b9e63[_0x227c31(0x3b9)](_0x469774=>{const _0x46c9b9=_0x227c31,_0x342af3=(_0x469774[_0x46c9b9(0x2db)]||[])[_0x46c9b9(0x3b9)](_0x46cd1f=>_0x46c9b9(0x4aa)==typeof _0x46cd1f?{'text':_0x46cd1f}:_0x46cd1f&&_0x46c9b9(0x2d2)==typeof _0x46cd1f?{'text':_0x481fa0(_0x46cd1f[_0x46c9b9(0x38e)]??'')}:{'text':_0x287e2f(_0x46cd1f??'')});_0x3a04d9(_0x342af3);const _0x5c2643=_0x342af3[_0x46c9b9(0x3b9)](_0x1fdb59=>_0x2dd29c(_0x1fdb59[_0x46c9b9(0x38e)]??'')),_0xcc1a57={};return _0xcc1a57['id']=_0x469774['id'],_0xcc1a57[_0x46c9b9(0x49d)]=_0x469774[_0x46c9b9(0x49d)],_0xcc1a57[_0x46c9b9(0x2db)]=_0x342af3,_0xcc1a57[_0x46c9b9(0x3ab)+_0x46c9b9(0x28d)]=_0x5c2643,_0xcc1a57;});}async['handleInit'](_0x2f7751,_0x14b2e3){const _0x13172f=_0x3b60da;try{if(this[_0x13172f(0x2cc)]=_0x2f7751['mode'],this[_0x13172f(0x3eb)]=_0x2f7751[_0x13172f(0x422)],this[_0x13172f(0x2f2)+'Id']=_0x2f7751[_0x13172f(0x2f2)+_0x13172f(0x492)]??null,this['studentId']=_0x2f7751['student_id']??null,this[_0x13172f(0x23d)]=_0x2f7751[_0x13172f(0x296)+'rl']??'',this[_0x13172f(0x234)]=_0x2f7751[_0x13172f(0x21f)]??'',!_0x403c12[_0x13172f(0x21b)][this[_0x13172f(0x3eb)]])throw new Error(_0x13172f(0x247)+_0x13172f(0x227)+this[_0x13172f(0x3eb)]);if(this[_0x13172f(0x48e)+_0x13172f(0x338)]=!0x0,this[_0x13172f(0x4a1)+'nt'](_0x1c043b[_0x13172f(0x3ce)+_0x13172f(0x483)][_0x13172f(0x2f8)],{'mode':this[_0x13172f(0x2cc)],'game_code':this[_0x13172f(0x3eb)]},_0x14b2e3),this[_0x13172f(0x36a)](_0x58db97[_0x13172f(0x271)],_0x13172f(0x423)+_0x13172f(0x290)+this[_0x13172f(0x2cc)]+(_0x13172f(0x272)+'e=')+this['gameCode']),_0x13172f(0x35f)===this[_0x13172f(0x2cc)]&&this[_0x13172f(0x2f2)+'Id'])await this[_0x13172f(0x49b)+_0x13172f(0x4de)]();else{if(_0x58db97['mlnCu'](_0x58db97['ZdmvF'],this['mode'])){if(_0x58db97[_0x13172f(0x4d6)]!==_0x13172f(0x4b3)){const _0x46c8b4=(0x0,_0x4ade6a[_0x13172f(0x203)+'a'])(this[_0x13172f(0x3eb)]);_0x46c8b4?(this[_0x13172f(0x36a)](_0x58db97['WlCtI'],_0x13172f(0x403)+_0x13172f(0x2c5)+'ta\x20for\x20'+this[_0x13172f(0x3eb)]),this[_0x13172f(0x4a5)+'a'](_0x46c8b4[_0x13172f(0x3c5)])):this[_0x13172f(0x2d5)](_0x58db97['NXqLi'],'No\x20mock\x20da'+_0x13172f(0x244)+_0x13172f(0x1d9)+this[_0x13172f(0x3eb)],_0x14b2e3);}else return _0x38b15a[_0x13172f(0x1db)](_0x46a22d[_0x13172f(0x1f2)]);}}}catch(_0x288546){_0x58db97['mlnCu'](_0x58db97[_0x13172f(0x44b)],_0x58db97[_0x13172f(0x34a)])?(this['originalIt'+_0x13172f(0x3f5)]['clear'](),_0x5c44cc['forEach'](_0x2a7111=>{const _0x17f399=_0x13172f;_0x2a7111['id']&&this[_0x17f399(0x1fa)+_0x17f399(0x3f5)][_0x17f399(0x34e)](_0x2a7111['id'],_0x2a7111);}),this[_0x13172f(0x2cf)+_0x13172f(0x3c2)][_0x13172f(0x3e6)](),_0x337d6a&&_0x500968[_0x13172f(0x4eb)](_0x29e03f=>this[_0x13172f(0x2cf)+_0x13172f(0x3c2)][_0x13172f(0x458)](_0x29e03f['id'])),this[_0x13172f(0x358)+'tems']=(0x0,_0x391d1a[_0x13172f(0x2aa)+_0x13172f(0x1fd)])(this[_0x13172f(0x3eb)],_0x3dc47e),this[_0x13172f(0x275)+'s'][_0x13172f(0x3e6)](),this[_0x13172f(0x358)+'tems'][_0x13172f(0x4eb)](_0x465ade=>{const _0x291af9=_0x13172f;_0x465ade['id']&&this[_0x291af9(0x275)+'s'][_0x291af9(0x34e)](_0x465ade['id'],_0x465ade);}),this[_0x13172f(0x4a1)+'nt'](_0x336c21['SDK_MESSAG'+_0x13172f(0x483)][_0x13172f(0x1fb)+_0x13172f(0x3b3)],{'items':this['sanitizedI'+_0x13172f(0x26c)],'total_questions':_0x40e03c[_0x13172f(0x24e)],'completed_count':this[_0x13172f(0x2cf)+_0x13172f(0x3c2)][_0x13172f(0x475)],'resume_data':_0x5e042b}),this[_0x13172f(0x36a)](_0x58db97[_0x13172f(0x271)],_0x13172f(0x414)+'ssed:\x20'+_0x1b6bc0['length']+_0x13172f(0x326)+this[_0x13172f(0x2cf)+_0x13172f(0x3c2)]['size']+_0x13172f(0x416))):this[_0x13172f(0x2d5)](_0x58db97[_0x13172f(0x4ad)],_0x288546['message'],_0x14b2e3);}}['handlePush'+_0x3b60da(0x430)](_0x1ff4f2,_0x329bb1){const _0xd88416=_0x3b60da,_0xeff678={};_0xeff678[_0xd88416(0x305)]=function(_0x545925,_0x38a61b){return _0x545925===_0x38a61b;},_0xeff678[_0xd88416(0x41c)]=_0xd88416(0x3be);const _0x5a6bc8=_0xeff678;if(_0x24a5c7[_0xd88416(0x4cd)](_0x24a5c7[_0xd88416(0x464)],_0x24a5c7[_0xd88416(0x464)])){if(this[_0xd88416(0x48e)+_0xd88416(0x338)]){if(_0x24a5c7[_0xd88416(0x24f)](_0xd88416(0x460),this[_0xd88416(0x2cc)]))try{_0x24a5c7[_0xd88416(0x1e7)]('urbdX',_0x24a5c7['SRyct'])?(_0x5a6bc8[_0xd88416(0x305)](void 0x0,_0x3047a9)&&(_0x57b6eb=_0x4d4f4e),_0x4d768f[_0x17db7b]=_0x37570d[_0x2c492c]):this['processDat'+'a'](_0x1ff4f2[_0xd88416(0x3c5)],_0x1ff4f2[_0xd88416(0x4b0)+_0xd88416(0x2cd)+'ds']);}catch(_0x1865dd){this[_0xd88416(0x2d5)](_0x24a5c7[_0xd88416(0x363)],_0x1865dd['message'],_0x329bb1);}else this[_0xd88416(0x2d5)](_0x24a5c7['Esfiu'],_0x24a5c7[_0xd88416(0x384)],_0x329bb1);}else this['sendError'](_0x24a5c7[_0xd88416(0x1e5)],'SDK\x20not\x20in'+'itialized.'+'\x20Call\x20SDK_'+_0xd88416(0x484)+'.',_0x329bb1);}else this[_0xd88416(0x2d5)](_0x5a6bc8[_0xd88416(0x41c)],_0x44c320[_0xd88416(0x225)],_0x4ba06a);}async[_0x3b60da(0x2ae)+'kAnswer'](_0x4ef627,_0x25e924){const _0x56890e=_0x3b60da,_0x59037b={'djkdb':function(_0x459026,_0x394eba){return _0x459026(_0x394eba);}};if(!this[_0x56890e(0x48e)+_0x56890e(0x338)]||0x0===this['originalIt'+_0x56890e(0x3f5)][_0x56890e(0x475)])return void this[_0x56890e(0x2d5)](_0x24a5c7[_0x56890e(0x3fa)],_0x24a5c7[_0x56890e(0x2a2)],_0x25e924);const {question_id:_0xec7ee5,choice:_0x24b8a3,time_spent:_0x584653=0x0}=_0x4ef627,_0x3fe3c3=this[_0x56890e(0x3eb)],_0x230c81=this[_0x56890e(0x275)+'s'][_0x56890e(0x3e1)](_0xec7ee5);let _0x98e16f=_0x24b8a3;switch(_0x3fe3c3){case _0x56890e(0x22e):case _0x24a5c7['PWnRz']:case _0x24a5c7['XWmIO']:case _0x56890e(0x266):case _0x24a5c7['NjHPp']:if(_0x230c81&&_0x24a5c7[_0x56890e(0x4dd)]('number',typeof _0x24b8a3)){if(_0x24a5c7[_0x56890e(0x1e7)]('wOtQw',_0x24a5c7[_0x56890e(0x4cf)])){const _0x38b3cc=(_0x294fe7[_0x56890e(0x2db)]||[])[_0x56890e(0x3b9)](_0x2201e1=>_0x56890e(0x4aa)==typeof _0x2201e1?{'text':_0x2201e1}:_0x2201e1&&_0x56890e(0x2d2)==typeof _0x2201e1?{'text':_0x442e8e(_0x2201e1[_0x56890e(0x38e)]??'')}:{'text':_0x5be723(_0x2201e1??'')});_0x59037b[_0x56890e(0x378)](_0x3117f2,_0x38b3cc);const _0x6bfeb1=_0x38b3cc[_0x56890e(0x3b9)](_0x3e40e4=>_0x4aa3bf(_0x3e40e4[_0x56890e(0x38e)]??'')),_0x352713={};return _0x352713['id']=_0x51db1b['id'],_0x352713[_0x56890e(0x49d)]=_0x49bfc2[_0x56890e(0x4d9)]||_0x704719[_0x56890e(0x3a0)],_0x352713[_0x56890e(0x2db)]=_0x38b3cc,_0x352713['__shuffled'+_0x56890e(0x28d)]=_0x6bfeb1,_0x352713;}else{const _0x2e8e9f=_0x230c81[_0x56890e(0x3ab)+_0x56890e(0x28d)];Array['isArray'](_0x2e8e9f)&&_0x24a5c7[_0x56890e(0x294)](_0x24b8a3,0x0)&&_0x24a5c7[_0x56890e(0x376)](_0x24b8a3,_0x2e8e9f[_0x56890e(0x24e)])&&(_0x98e16f=_0x2e8e9f[_0x24b8a3],this[_0x56890e(0x36a)](_0x24a5c7[_0x56890e(0x39d)],'['+_0x3fe3c3+(_0x56890e(0x26d)+_0x56890e(0x230))+_0x24b8a3+_0x56890e(0x425)+_0x98e16f+'\x22'));}}break;case _0x24a5c7[_0x56890e(0x224)]:case _0x24a5c7[_0x56890e(0x4ac)]:case _0x24a5c7[_0x56890e(0x3bb)]:case _0x24a5c7[_0x56890e(0x2a9)]:case _0x24a5c7[_0x56890e(0x4d8)]:case _0x24a5c7[_0x56890e(0x3d9)]:case _0x56890e(0x404):case _0x24a5c7['LknAV']:this[_0x56890e(0x36a)](_0x24a5c7[_0x56890e(0x39d)],'['+_0x3fe3c3+(']\x20Answer\x20a'+'rray:\x20')+JSON['stringify'](_0x24b8a3));break;default:this[_0x56890e(0x36a)]('warn',_0x56890e(0x3fd)+'me\x20code:\x20'+_0x3fe3c3+(',\x20using\x20ra'+_0x56890e(0x4e1)));}const _0x1a1ca2=this[_0x56890e(0x1fa)+'ems'][_0x56890e(0x3e1)](_0xec7ee5);if(_0x1a1ca2){if(_0x24a5c7[_0x56890e(0x246)](_0x56890e(0x460),this[_0x56890e(0x2cc)])||_0x24a5c7[_0x56890e(0x499)](_0x56890e(0x4e5),this[_0x56890e(0x2cc)])){if(_0x24a5c7[_0x56890e(0x43f)](_0x24a5c7['vOpTn'],_0x24a5c7[_0x56890e(0x4be)]))return _0x5c1cf0['GAME_CODES'][_0x439592]?.[_0x56890e(0x38c)]||_0x58db97[_0x56890e(0x386)];else{const _0x19e837=(0x0,_0x403c12[_0x56890e(0x297)+'r'])(this[_0x56890e(0x3eb)],_0x1a1ca2,_0x98e16f),_0x1a7255={'question_id':_0xec7ee5,'choice':_0x24b8a3,'answer_value':_0x98e16f,'correct':_0x19e837['isCorrect'],'score':_0x19e837[_0x56890e(0x4da)],'synced':!0x0,'time_spent':_0x584653};return this[_0x56890e(0x1e6)+'s'][_0x56890e(0x34e)](_0xec7ee5,_0x1a7255),this[_0x56890e(0x4a1)+'nt'](_0x1c043b[_0x56890e(0x3ce)+'E_TYPES'][_0x56890e(0x2dc)+_0x56890e(0x4ca)],{'question_id':_0xec7ee5,'correct':_0x19e837[_0x56890e(0x25c)],'score':_0x19e837[_0x56890e(0x4da)],'synced':!0x0},_0x25e924),void this[_0x56890e(0x36a)](_0x24a5c7['dHvqQ'],'[Local]\x20An'+_0x56890e(0x43d)+_0x56890e(0x28e)+'\x20('+this['mode']+_0x56890e(0x1ec)+_0xec7ee5+_0x56890e(0x3b7)+_0x19e837[_0x56890e(0x25c)]);}}try{const _0x49c1ba=await this['submitAnsw'+_0x56890e(0x20e)](_0xec7ee5,_0x98e16f,_0x584653),_0x5c0764={'question_id':_0xec7ee5,'choice':_0x24b8a3,'answer_value':_0x98e16f,'correct':_0x49c1ba[_0x56890e(0x2b4)],'score':_0x49c1ba[_0x56890e(0x4da)],'synced':!0x0,'time_spent':_0x584653};this[_0x56890e(0x1e6)+'s']['set'](_0xec7ee5,_0x5c0764),this['sendToPare'+'nt'](_0x1c043b['SDK_MESSAG'+_0x56890e(0x483)]['SDK_ANSWER'+'_RESULT'],{'question_id':_0xec7ee5,'correct':_0x49c1ba[_0x56890e(0x2b4)],'score':_0x49c1ba[_0x56890e(0x4da)],'synced':!0x0},_0x25e924),this[_0x56890e(0x36a)](_0x24a5c7[_0x56890e(0x410)],_0x56890e(0x239)+_0x56890e(0x49a)+'ed\x20by\x20serv'+_0x56890e(0x29e)+_0xec7ee5+_0x56890e(0x3b7)+_0x49c1ba['correct']);}catch(_0x3109da){this[_0x56890e(0x2d5)](_0x24a5c7['AQVSr'],_0x3109da[_0x56890e(0x225)]||_0x24a5c7[_0x56890e(0x295)],_0x25e924),this[_0x56890e(0x36a)](_0x56890e(0x440),'[Live]\x20Fai'+_0x56890e(0x1ff)+_0x56890e(0x474)+':\x20'+_0xec7ee5,_0x3109da);}}else this[_0x56890e(0x2d5)](_0x24a5c7['vivdY'],_0x56890e(0x417)+_0xec7ee5+_0x56890e(0x40c),_0x25e924);}async[_0x3b60da(0x450)+_0x3b60da(0x20e)](_0x3fa562,_0x1cda13,_0x11021b){const _0x5a3fc3=_0x3b60da;if(!this[_0x5a3fc3(0x23d)]||!this[_0x5a3fc3(0x2f2)+'Id'])throw new Error(_0x58db97[_0x5a3fc3(0x368)]);const _0x21125a={};_0x21125a[_0x5a3fc3(0x2b1)+'pe']='applicatio'+_0x5a3fc3(0x39e);const _0x5e7f10=this[_0x5a3fc3(0x23d)]+(_0x5a3fc3(0x400)+_0x5a3fc3(0x2f3)+_0x5a3fc3(0x1e2)),_0x1fd361=_0x21125a;this[_0x5a3fc3(0x234)]&&(_0x1fd361[_0x5a3fc3(0x4e7)+_0x5a3fc3(0x3c9)]=_0x5a3fc3(0x46a)+this[_0x5a3fc3(0x234)]);const _0x3c7e68={};_0x3c7e68[_0x5a3fc3(0x2f2)+_0x5a3fc3(0x492)]=this[_0x5a3fc3(0x2f2)+'Id'],_0x3c7e68[_0x5a3fc3(0x30c)]=this[_0x5a3fc3(0x31a)],_0x3c7e68[_0x5a3fc3(0x2cd)+'d']=_0x3fa562,_0x3c7e68['selected_a'+'nswer']=_0x1cda13,_0x3c7e68[_0x5a3fc3(0x29d)]=_0x11021b,_0x3c7e68[_0x5a3fc3(0x456)]=!0x1;const _0x16ea17=await fetch(_0x5e7f10,{'method':_0x58db97[_0x5a3fc3(0x3ba)],'headers':_0x1fd361,'body':JSON[_0x5a3fc3(0x3ef)](_0x3c7e68)});if(!_0x16ea17['ok']){const _0x4f0943=await _0x16ea17[_0x5a3fc3(0x2ce)]()[_0x5a3fc3(0x42a)](()=>({}));throw new Error(_0x4f0943[_0x5a3fc3(0x225)]||_0x5a3fc3(0x1ef)+_0x5a3fc3(0x2e8)+_0x16ea17[_0x5a3fc3(0x408)]);}const _0x50d8f0=await _0x16ea17[_0x5a3fc3(0x2ce)](),_0x212789={};return _0x212789[_0x5a3fc3(0x2b4)]=_0x50d8f0[_0x5a3fc3(0x2b4)]??!0x1,_0x212789[_0x5a3fc3(0x4da)]=_0x50d8f0[_0x5a3fc3(0x4da)]??(_0x50d8f0[_0x5a3fc3(0x2b4)]?0x1:0x0),_0x212789;}[_0x3b60da(0x3e2)+'esult'](_0x21305a){const _0x2ab9e0=_0x3b60da,_0x14b826=Array[_0x2ab9e0(0x443)](this[_0x2ab9e0(0x1e6)+'s']['values']())[_0x2ab9e0(0x3b9)](_0x4cfee4=>({'question_id':_0x4cfee4[_0x2ab9e0(0x2cd)+'d'],'choice':_0x4cfee4[_0x2ab9e0(0x1e9)],'correct':_0x4cfee4['correct'],'synced':_0x4cfee4['synced'],'time_spent':_0x4cfee4[_0x2ab9e0(0x29d)]})),_0x3087c3=_0x14b826[_0x2ab9e0(0x257)](_0x5e0ca9=>_0x5e0ca9[_0x2ab9e0(0x2b4)])[_0x2ab9e0(0x24e)],_0x20295a=this[_0x2ab9e0(0x1fa)+'ems']['size'],_0xb49748=_0x14b826[_0x2ab9e0(0x1f4)](_0x568d73=>_0x568d73[_0x2ab9e0(0x4bc)]);this[_0x2ab9e0(0x4a1)+'nt'](_0x1c043b['SDK_MESSAG'+_0x2ab9e0(0x483)][_0x2ab9e0(0x441)+_0x2ab9e0(0x30e)],{'score':_0x24a5c7['eFzNp'](_0x20295a,0x0)?Math[_0x2ab9e0(0x40f)](_0x24a5c7[_0x2ab9e0(0x3cc)](_0x3087c3/_0x20295a,0x64)):0x0,'total':_0x20295a,'correct':_0x3087c3,'wrong':_0x24a5c7[_0x2ab9e0(0x2ac)](_0x20295a,_0x3087c3),'synced':_0xb49748,'details':_0x14b826},_0x21305a);}async['handleRetr'+_0x3b60da(0x321)](_0x192b6f,_0x586f42){const _0x417d60=_0x3b60da,_0x3d6049=this['userAnswer'+'s'][_0x417d60(0x3e1)](_0x192b6f[_0x417d60(0x2cd)+'d']),_0x3146f7={};_0x3146f7[_0x417d60(0x2cd)+'d']=_0x192b6f[_0x417d60(0x2cd)+'d'],_0x3146f7['synced']=!0x0;if(_0x3d6049){if(_0x3d6049[_0x417d60(0x4bc)])this['sendToPare'+'nt'](_0x1c043b[_0x417d60(0x3ce)+_0x417d60(0x483)][_0x417d60(0x1f7)+_0x417d60(0x221)],_0x3146f7,_0x586f42);else try{const _0x544de5=await this['submitAnsw'+_0x417d60(0x20e)](_0x3d6049[_0x417d60(0x2cd)+'d'],_0x3d6049[_0x417d60(0x4b2)+'ue'],_0x3d6049[_0x417d60(0x29d)]);_0x3d6049[_0x417d60(0x2b4)]=_0x544de5['correct'],_0x3d6049['score']=_0x544de5[_0x417d60(0x4da)],_0x3d6049[_0x417d60(0x4bc)]=!0x0,this[_0x417d60(0x4a1)+'nt'](_0x1c043b[_0x417d60(0x3ce)+_0x417d60(0x483)][_0x417d60(0x1f7)+_0x417d60(0x221)],{'question_id':_0x192b6f[_0x417d60(0x2cd)+'d'],'synced':!0x0,'server_result':_0x544de5},_0x586f42);}catch(_0x55308b){if(_0x24a5c7[_0x417d60(0x24b)](_0x24a5c7[_0x417d60(0x201)],'JENPE')){const _0x6dffa7={};_0x6dffa7[_0x417d60(0x37f)]=_0xd88de9;if(_0x58db97[_0x417d60(0x31b)]==typeof _0x898e9a)return _0x6dffa7;if(_0x101ea8&&_0x58db97['LxZPf'](_0x58db97['qoRIS'],typeof _0x388369)){const _0x303016=_0x3d2925['image_url']||_0x525271[_0x417d60(0x3e5)]||'';return{'image_url':_0x58db97[_0x417d60(0x2d8)](_0x5e70c1,_0x303016)};}return{'image_url':_0x58db97[_0x417d60(0x479)](_0x1422cc,_0x58db97[_0x417d60(0x351)](_0x288c4a,''))};}else this[_0x417d60(0x2d5)](_0x24a5c7[_0x417d60(0x46c)],_0x55308b[_0x417d60(0x225)]||_0x417d60(0x3cd)+'ed',_0x586f42);}}else this[_0x417d60(0x2d5)](_0x24a5c7['eLPjG'],_0x417d60(0x4a2)+'\x20'+_0x192b6f[_0x417d60(0x2cd)+'d']+_0x417d60(0x40c),_0x586f42);}['processDat'+'a'](_0x2e67f4,_0x112d5f){const _0x3df661=_0x3b60da;_0x3df661(0x4e6)!==_0x58db97['FNSWU']?(this[_0x3df661(0x465)+'geHandler']=this[_0x3df661(0x3f4)+_0x3df661(0x33e)][_0x3df661(0x415)](this),_0x5b61f6[_0x3df661(0x259)+_0x3df661(0x3ec)](_0x58db97[_0x3df661(0x34d)],this[_0x3df661(0x465)+_0x3df661(0x42d)])):(this[_0x3df661(0x1fa)+'ems'][_0x3df661(0x3e6)](),_0x2e67f4[_0x3df661(0x4eb)](_0x13dd2b=>{const _0x5b7402=_0x3df661,_0x17fdb4={'mOPpH':function(_0x4f651c,_0x4df669){const _0x31e6e4=a0_0x3575;return _0x58db97[_0x31e6e4(0x479)](_0x4f651c,_0x4df669);}};if(_0x58db97[_0x5b7402(0x2bc)]!==_0x58db97[_0x5b7402(0x2bc)]){const _0xe3a3ab=_0x1025d4[_0x5b7402(0x37f)]||_0x1581d8['image']||'';return{'image_url':_0x17fdb4[_0x5b7402(0x2a1)](_0x30c085,_0xe3a3ab)};}else _0x13dd2b['id']&&this[_0x5b7402(0x1fa)+_0x5b7402(0x3f5)][_0x5b7402(0x34e)](_0x13dd2b['id'],_0x13dd2b);}),this[_0x3df661(0x2cf)+'uestions'][_0x3df661(0x3e6)](),_0x112d5f&&_0x112d5f['forEach'](_0x45277a=>this[_0x3df661(0x2cf)+_0x3df661(0x3c2)][_0x3df661(0x458)](_0x45277a['id'])),this[_0x3df661(0x358)+_0x3df661(0x26c)]=(0x0,_0x403c12[_0x3df661(0x2aa)+_0x3df661(0x1fd)])(this[_0x3df661(0x3eb)],_0x2e67f4),this[_0x3df661(0x275)+'s'][_0x3df661(0x3e6)](),this['sanitizedI'+_0x3df661(0x26c)][_0x3df661(0x4eb)](_0x2c0f29=>{const _0xf06e94=_0x3df661;_0x2c0f29['id']&&this[_0xf06e94(0x275)+'s'][_0xf06e94(0x34e)](_0x2c0f29['id'],_0x2c0f29);}),this['sendToPare'+'nt'](_0x1c043b[_0x3df661(0x3ce)+'E_TYPES'][_0x3df661(0x1fb)+_0x3df661(0x3b3)],{'items':this[_0x3df661(0x358)+_0x3df661(0x26c)],'total_questions':_0x2e67f4[_0x3df661(0x24e)],'completed_count':this[_0x3df661(0x2cf)+_0x3df661(0x3c2)][_0x3df661(0x475)],'resume_data':_0x112d5f}),this[_0x3df661(0x36a)](_0x3df661(0x212),_0x3df661(0x414)+'ssed:\x20'+_0x2e67f4[_0x3df661(0x24e)]+_0x3df661(0x326)+this[_0x3df661(0x2cf)+'uestions']['size']+_0x3df661(0x416)));}async[_0x3b60da(0x49b)+_0x3b60da(0x4de)](){const _0x307bbf=_0x3b60da;if(this[_0x307bbf(0x23d)]&&this['assignment'+'Id'])try{if(_0x24a5c7['YAxPN']('ooAbq',_0x307bbf(0x3f6))){const _0x1be582={};_0x1be582['Content-Ty'+'pe']=_0x24a5c7[_0x307bbf(0x2a4)];const _0x315d7f=this[_0x307bbf(0x23d)]+_0x307bbf(0x1da)+this['assignment'+'Id'],_0x1df0b1=_0x1be582;this['authToken']&&(_0x1df0b1['Authorizat'+_0x307bbf(0x3c9)]=_0x307bbf(0x46a)+this[_0x307bbf(0x234)]),this[_0x307bbf(0x36a)](_0x307bbf(0x212),_0x307bbf(0x217)+_0x307bbf(0x302)+_0x315d7f);const _0x1a2949={};_0x1a2949['headers']=_0x1df0b1;const _0x2636c7=await _0x24a5c7[_0x307bbf(0x457)](fetch,_0x315d7f,_0x1a2949);if(!_0x2636c7['ok'])throw new Error(_0x307bbf(0x20c)+'\x20'+_0x2636c7[_0x307bbf(0x408)]);const _0x17131d=await _0x2636c7['json'](),_0x4054b6=_0x17131d[_0x307bbf(0x3c5)]||_0x17131d['items']||_0x17131d[_0x307bbf(0x4d1)]||[],_0x221776=_0x17131d[_0x307bbf(0x4b0)+_0x307bbf(0x2cd)+'ds']||[];this['processDat'+'a'](_0x4054b6,_0x221776);}else return{'type':_0x60f604,'payload':_0x12c831,'timestamp':_0x18754e[_0x307bbf(0x366)](),'request_id':_0x38c36c};}catch(_0x501765){_0x24a5c7['oYgcD'](_0x24a5c7[_0x307bbf(0x3f2)],_0x24a5c7['UFdRU'])?this['processDat'+'a'](_0x32f1d3['data'],_0x3b85d7[_0x307bbf(0x4b0)+'question_i'+'ds']):(this['log']('error','Failed\x20to\x20'+_0x307bbf(0x202)+_0x307bbf(0x22d),_0x501765),this[_0x307bbf(0x2d5)](_0x307bbf(0x4c3)+'R',_0x501765['message']));}else this[_0x307bbf(0x2d5)](_0x24a5c7[_0x307bbf(0x406)],_0x307bbf(0x3a4)+'iBaseUrl\x20o'+_0x307bbf(0x47c)+_0x307bbf(0x219)+'ive\x20mode');}[_0x3b60da(0x4a1)+'nt'](_0x13b365,_0x456b1c,_0x1055d9){const _0x3a23a9=_0x3b60da,_0x1e5ed2=(0x0,_0x1c043b[_0x3a23a9(0x2ee)+'essage'])(_0x13b365,_0x456b1c,_0x1055d9),_0x38fd5=this['parentOrig'+'in'],_0x43fcc0=_0x38fd5&&_0x24a5c7['hyauh'](_0x24a5c7['lsjEv'],_0x38fd5)?_0x38fd5:'*';window['parent'][_0x3a23a9(0x41f)+'e'](_0x1e5ed2,_0x43fcc0),this['log'](_0x24a5c7['zruSA'],_0x3a23a9(0x3ed)+_0x13b365,_0x456b1c);}[_0x3b60da(0x2d5)](_0x5d073e,_0x1f97af,_0x4af341){const _0x52b40e=_0x3b60da;if(_0x24a5c7[_0x52b40e(0x3ff)](_0x52b40e(0x356),_0x24a5c7[_0x52b40e(0x240)])){const _0x20fa11={};_0x20fa11[_0x52b40e(0x4ce)]=_0x5d073e,_0x20fa11[_0x52b40e(0x225)]=_0x1f97af,(this[_0x52b40e(0x4a1)+'nt'](_0x1c043b[_0x52b40e(0x3ce)+'E_TYPES']['SDK_ERROR'],_0x20fa11,_0x4af341),this['log'](_0x52b40e(0x440),'Error:\x20'+_0x5d073e+'\x20-\x20'+_0x1f97af));}else for(let _0x4669a8=_0x58db97[_0x52b40e(0x21c)](_0x2aa880[_0x52b40e(0x24e)],0x1);_0x58db97[_0x52b40e(0x3fb)](_0x4669a8,0x0);_0x4669a8--){const _0x4a1339=_0x28711f[_0x52b40e(0x2e9)](_0x58db97[_0x52b40e(0x1de)](_0x1f7ab3['random'](),_0x58db97['ojBQJ'](_0x4669a8,0x1)));[_0x184456[_0x4669a8],_0x2d4ef1[_0x4a1339]]=[_0x314fac[_0x4a1339],_0x1a908e[_0x4669a8]];}}[_0x3b60da(0x36a)](_0x2fa90e,_0x4d87a1,_0x169784){const _0x2929c0=_0x3b60da;if(!this[_0x2929c0(0x2b3)][_0x2929c0(0x336)]&&_0x58db97[_0x2929c0(0x3d0)](_0x58db97[_0x2929c0(0x398)],_0x2fa90e))return;const _0x301850=_0x58db97['ItlBX'];switch(_0x2fa90e){case _0x58db97['SpwIg']:case _0x58db97[_0x2929c0(0x271)]:console['log'](_0x301850,_0x4d87a1,_0x58db97[_0x2929c0(0x2e2)](_0x169784,''));break;case _0x2929c0(0x3e9):console[_0x2929c0(0x3e9)](_0x301850,_0x4d87a1,_0x58db97[_0x2929c0(0x3a7)](_0x169784,''));break;case _0x58db97['MHgxN']:console['error'](_0x301850,_0x4d87a1,_0x169784??'');}}['destroy'](){const _0x81a3c8=_0x3b60da;_0x58db97['SyJVz'](_0x81a3c8(0x346),_0x58db97['hojSH'])?(this['sendError'](_0x58db97[_0x81a3c8(0x204)],_0x42fcfc[_0x81a3c8(0x225)]||_0x58db97[_0x81a3c8(0x428)],_0x221de8),this[_0x81a3c8(0x36a)](_0x58db97['MHgxN'],_0x81a3c8(0x2a7)+_0x81a3c8(0x1ff)+_0x81a3c8(0x474)+':\x20'+_0xf0d709,_0x30f668)):(this[_0x81a3c8(0x465)+'geHandler']&&(window[_0x81a3c8(0x213)+_0x81a3c8(0x35e)](_0x81a3c8(0x225),this[_0x81a3c8(0x465)+_0x81a3c8(0x42d)]),this[_0x81a3c8(0x465)+'geHandler']=null),this[_0x81a3c8(0x1fa)+_0x81a3c8(0x3f5)][_0x81a3c8(0x3e6)](),this[_0x81a3c8(0x1e6)+'s'][_0x81a3c8(0x3e6)](),this['log'](_0x58db97[_0x81a3c8(0x271)],_0x58db97[_0x81a3c8(0x47d)]));}}_0x559ab7[_0x3b60da(0x1e3)+_0x3b60da(0x392)]=_0x286974,_0x24a5c7[_0x3b60da(0x2fb)](_0x24a5c7[_0x3b60da(0x39f)],typeof window)&&(window['SdkIframe']=new _0x286974({'debug':_0x24a5c7['hhmiz'](_0x24a5c7['xYiju'],new URLSearchParams(window[_0x3b60da(0x48f)]['search'])[_0x3b60da(0x3e1)](_0x24a5c7[_0x3b60da(0x39d)]))}));}},0x23e(_0x52bf2e,_0x3c9189,_0x22ea51){const _0x3337eb=_0x41c3f4,_0x1e23a5={'uSRff':_0x24a5c7['zruSA'],'wNrFQ':function(_0x45f9bd,_0x3dc0b6){const _0x8160e2=a0_0x3575;return _0x24a5c7[_0x8160e2(0x4cd)](_0x45f9bd,_0x3dc0b6);},'POCoj':_0x24a5c7[_0x3337eb(0x436)],'fxDew':function(_0x4e5c83,_0x34e71e){const _0x2129ea=_0x3337eb;return _0x24a5c7[_0x2129ea(0x499)](_0x4e5c83,_0x34e71e);},'Pgfuv':function(_0x3ef6f3,_0xb7f9c5){return _0x24a5c7['ODOhn'](_0x3ef6f3,_0xb7f9c5);},'uZLwo':_0x24a5c7[_0x3337eb(0x211)]};var _0x25e84a=this&&this[_0x3337eb(0x3a8)+_0x3337eb(0x482)]||(Object[_0x3337eb(0x40a)]?function(_0xde06ad,_0x15722d,_0x349ba6,_0x4c1cc5){const _0x4366b3=_0x3337eb;_0x1e23a5['fxDew'](void 0x0,_0x4c1cc5)&&(_0x4c1cc5=_0x349ba6);var _0x2453ef=Object[_0x4366b3(0x349)+'ertyDescri'+'ptor'](_0x15722d,_0x349ba6);_0x2453ef&&!(_0x1e23a5[_0x4366b3(0x236)](_0x1e23a5[_0x4366b3(0x350)],_0x2453ef)?!_0x15722d[_0x4366b3(0x2df)]:_0x2453ef['writable']||_0x2453ef['configurab'+'le'])||(_0x2453ef={'enumerable':!0x0,'get':function(){const _0x5e0352=_0x4366b3,_0x26ab0e={};_0x26ab0e[_0x5e0352(0x2ad)]=_0x1e23a5[_0x5e0352(0x3f8)];const _0xbefd10=_0x26ab0e;if(_0x1e23a5[_0x5e0352(0x453)](_0x1e23a5[_0x5e0352(0x327)],_0x1e23a5[_0x5e0352(0x327)]))return _0x15722d[_0x349ba6];else{const _0x48a9e7=_0x5dbb94[_0x5e0352(0x3ab)+'Options'];_0x422ff5[_0x5e0352(0x2f9)](_0x48a9e7)&&_0x316f57>=0x0&&_0x5205e1<_0x48a9e7[_0x5e0352(0x24e)]&&(_0x142562=_0x48a9e7[_0x23070c],this['log'](_0xbefd10[_0x5e0352(0x2ad)],'['+_0x55f7f0+(_0x5e0352(0x26d)+':\x20index\x20')+_0x5ccd37+_0x5e0352(0x425)+_0x5831f6+'\x22'));}}}),Object[_0x4366b3(0x1ea)+'erty'](_0xde06ad,_0x4c1cc5,_0x2453ef);}:function(_0x571993,_0x4862ed,_0x2bed21,_0x34b4a0){_0x1e23a5['wNrFQ'](void 0x0,_0x34b4a0)&&(_0x34b4a0=_0x2bed21),_0x571993[_0x34b4a0]=_0x4862ed[_0x2bed21];}),_0x4a9715=this&&this['__exportSt'+'ar']||function(_0x4cf1bb,_0x1e0690){const _0x4b354c=_0x3337eb;for(var _0x3a0c9f in _0x4cf1bb)_0x24a5c7['WSAzE'](_0x24a5c7[_0x4b354c(0x4c9)],_0x3a0c9f)||Object[_0x4b354c(0x2e4)][_0x4b354c(0x2bf)+'erty'][_0x4b354c(0x2d6)](_0x1e0690,_0x3a0c9f)||_0x24a5c7['jgCLh'](_0x25e84a,_0x1e0690,_0x4cf1bb,_0x3a0c9f);};const _0x554443={};_0x554443['value']=!0x0,(Object[_0x3337eb(0x1ea)+_0x3337eb(0x41e)](_0x3c9189,_0x24a5c7[_0x3337eb(0x360)],_0x554443),_0x3c9189['SdkIframeC'+'ore']=void 0x0);const _0x1ae1f5=_0x22ea51(0xb9),_0x25afe5={};_0x25afe5[_0x3337eb(0x21a)]=!0x0,_0x25afe5['get']=function(){const _0x372a88=_0x3337eb;return _0x1ae1f5[_0x372a88(0x1e3)+_0x372a88(0x392)];},(Object[_0x3337eb(0x1ea)+_0x3337eb(0x41e)](_0x3c9189,_0x24a5c7['vyCIX'],_0x25afe5),_0x24a5c7[_0x3337eb(0x1f9)](_0x4a9715,_0x24a5c7[_0x3337eb(0x3d8)](_0x22ea51,0x3c7),_0x3c9189),_0x24a5c7[_0x3337eb(0x42f)](_0x24a5c7['NmRZL'],typeof window)&&(window['SdkIframeC'+_0x3337eb(0x392)]=_0x1ae1f5[_0x3337eb(0x1e3)+'ore']));},0x2ba(_0x55d7a9,_0x313427){const _0x3febbd=_0x41c3f4,_0x22aa15={};_0x22aa15[_0x3febbd(0x304)]=!0x0,(Object[_0x3febbd(0x1ea)+'erty'](_0x313427,_0x24a5c7[_0x3febbd(0x360)],_0x22aa15),_0x313427[_0x3febbd(0x1f2)]=_0x313427[_0x3febbd(0x243)]=_0x313427[_0x3febbd(0x480)]=_0x313427[_0x3febbd(0x3cb)]=_0x313427[_0x3febbd(0x25d)]=_0x313427[_0x3febbd(0x4c1)]=_0x313427['MOCK_G112']=_0x313427['MOCK_G111']=_0x313427['MOCK_G110']=_0x313427[_0x3febbd(0x4df)]=_0x313427[_0x3febbd(0x487)]=_0x313427[_0x3febbd(0x4b5)]=_0x313427[_0x3febbd(0x2a5)]=_0x313427[_0x3febbd(0x353)]=void 0x0,_0x313427['getMockDat'+'a']=function(_0x13bc88){const _0x4a16e1=_0x3febbd;return _0x313427[_0x4a16e1(0x1f2)][_0x13bc88]??null;},_0x313427['getAvailab'+_0x3febbd(0x3a6)+'s']=function(){const _0x273029=_0x3febbd;return Object[_0x273029(0x1db)](_0x313427[_0x273029(0x1f2)]);},_0x313427['MOCK_G001']={'game_code':_0x24a5c7[_0x3febbd(0x401)],'game_id':_0x24a5c7[_0x3febbd(0x3ea)],'data':[{'id':'q1','question':_0x24a5c7[_0x3febbd(0x390)],'options':[_0x24a5c7[_0x3febbd(0x220)],_0x3febbd(0x320)+'h',_0x3febbd(0x4ed),_0x24a5c7[_0x3febbd(0x49f)]],'answer':0x0},{'id':'q2','question':_0x24a5c7[_0x3febbd(0x3e3)],'options':['3','4','5','6'],'answer':0x1},{'id':'q3','question':_0x3febbd(0x3e7)+'o\x20biết\x20bay'+'?','options':[_0x24a5c7[_0x3febbd(0x447)],_0x3febbd(0x37e),_0x24a5c7[_0x3febbd(0x41a)],'Cá'],'answer':0x2}]},_0x313427[_0x3febbd(0x2a5)]={'game_code':_0x24a5c7[_0x3febbd(0x4e8)],'game_id':_0x24a5c7[_0x3febbd(0x36d)],'data':[{'id':'q1','question_audio':_0x24a5c7[_0x3febbd(0x4b7)],'options':[_0x24a5c7[_0x3febbd(0x48b)],_0x3febbd(0x399),_0x24a5c7['ugmiz'],_0x24a5c7[_0x3febbd(0x26a)]],'answer':0x0},{'id':'q2','question_audio':_0x24a5c7[_0x3febbd(0x452)],'options':[_0x24a5c7[_0x3febbd(0x27d)],_0x24a5c7[_0x3febbd(0x3c7)],_0x24a5c7[_0x3febbd(0x44e)],_0x24a5c7[_0x3febbd(0x2a6)]],'answer':0x2}]},_0x313427[_0x3febbd(0x4b5)]={'game_code':_0x24a5c7[_0x3febbd(0x473)],'game_id':_0x24a5c7[_0x3febbd(0x29f)],'data':[{'id':'q1','question':_0x24a5c7['vyzPG'],'options':[_0x24a5c7['YPPZO'],_0x24a5c7[_0x3febbd(0x2fe)],_0x3febbd(0x208)+'ample.com/'+_0x3febbd(0x2fa)+_0x3febbd(0x3d2)],'answer':0x0}]},_0x313427[_0x3febbd(0x487)]={'game_code':_0x24a5c7[_0x3febbd(0x328)],'game_id':_0x24a5c7[_0x3febbd(0x3f1)],'data':[{'id':'q1','question_image':_0x24a5c7[_0x3febbd(0x2ab)],'question':_0x24a5c7[_0x3febbd(0x27b)],'options':[_0x24a5c7[_0x3febbd(0x451)],'Cam',_0x24a5c7[_0x3febbd(0x232)],_0x24a5c7[_0x3febbd(0x242)]],'answer':0x0},{'id':'q2','question_image':_0x24a5c7[_0x3febbd(0x4d5)],'options':[_0x24a5c7[_0x3febbd(0x447)],'Mèo',_0x24a5c7[_0x3febbd(0x1f1)],_0x24a5c7[_0x3febbd(0x315)]],'answer':0x1}]},_0x313427[_0x3febbd(0x4df)]={'game_code':'G005','game_id':_0x24a5c7[_0x3febbd(0x23e)],'data':[{'id':'q1','question':_0x24a5c7[_0x3febbd(0x200)],'options':[_0x24a5c7['wKOhE'],_0x24a5c7['lUkmZ'],'https://ex'+_0x3febbd(0x437)+'images/bir'+_0x3febbd(0x486)],'answer':0x1}]},_0x313427[_0x3febbd(0x3b8)]={'game_code':_0x24a5c7[_0x3febbd(0x224)],'game_id':_0x24a5c7['nKpsr'],'data':[{'id':_0x24a5c7[_0x3febbd(0x226)],'word':_0x24a5c7[_0x3febbd(0x47f)],'parts':['A','P','P','L','E'],'answer':['A','P','P','L','E']},{'id':_0x24a5c7[_0x3febbd(0x306)],'word':_0x3febbd(0x33a),'parts':['H','E','L','L','O'],'answer':['H','E','L','L','O']},{'id':_0x24a5c7['wrQhY'],'word':_0x24a5c7[_0x3febbd(0x44d)],'parts':['W','O','R','L','D'],'answer':['W','O','R','L','D']}]},_0x313427[_0x3febbd(0x45d)]={'game_code':_0x3febbd(0x2e0),'game_id':_0x24a5c7[_0x3febbd(0x26e)],'data':[{'id':_0x24a5c7[_0x3febbd(0x226)],'word':'BANANA','parts':['B','A','N','A','N','A'],'answer':['B','A','N','A','N','A'],'audio_url':_0x24a5c7[_0x3febbd(0x3ad)]}]},_0x313427[_0x3febbd(0x2b6)]={'game_code':_0x24a5c7['ZlQbN'],'game_id':_0x24a5c7[_0x3febbd(0x31d)],'data':[{'id':_0x3febbd(0x444),'word':_0x3febbd(0x24d),'parts':['C','O','M','P','U','T','E','R'],'answer':['C','O','M','P','U','T','E','R'],'audio_url':_0x24a5c7[_0x3febbd(0x1e1)]}]},_0x313427[_0x3febbd(0x4c1)]={'game_code':_0x24a5c7[_0x3febbd(0x2a9)],'game_id':_0x24a5c7[_0x3febbd(0x3a5)],'data':[{'id':_0x3febbd(0x444),'word':_0x3febbd(0x45c),'parts':['E','L','E','P','H','A','N','T'],'answer':['E','L','E','P','H','A','N','T'],'audio_url':_0x24a5c7[_0x3febbd(0x22f)]}]},_0x313427[_0x3febbd(0x25d)]={'game_code':_0x24a5c7['dMxuh'],'game_id':_0x24a5c7[_0x3febbd(0x39c)],'data':[{'id':_0x24a5c7[_0x3febbd(0x345)],'sentence':_0x24a5c7[_0x3febbd(0x411)],'parts':['I',_0x3febbd(0x285),_0x24a5c7[_0x3febbd(0x252)],_0x24a5c7[_0x3febbd(0x32a)]],'answer':['I',_0x24a5c7[_0x3febbd(0x4d3)],_0x24a5c7[_0x3febbd(0x252)],_0x24a5c7[_0x3febbd(0x32a)]]},{'id':_0x24a5c7[_0x3febbd(0x41b)],'sentence':_0x24a5c7['eaWsL'],'parts':[_0x24a5c7[_0x3febbd(0x46d)],_0x24a5c7[_0x3febbd(0x4cb)],'is',_0x24a5c7[_0x3febbd(0x446)]],'answer':[_0x24a5c7[_0x3febbd(0x46d)],_0x3febbd(0x31c),'is',_0x24a5c7[_0x3febbd(0x446)]]}]},_0x313427[_0x3febbd(0x3cb)]={'game_code':'G121','game_id':_0x3febbd(0x34f)+_0x3febbd(0x24c)+_0x3febbd(0x33f),'data':[{'id':_0x3febbd(0x2e5),'sentence':_0x24a5c7[_0x3febbd(0x260)],'parts':['She',_0x24a5c7[_0x3febbd(0x245)],'to','school',_0x24a5c7[_0x3febbd(0x2d4)],_0x24a5c7[_0x3febbd(0x4d4)]],'answer':[_0x3febbd(0x284),_0x24a5c7[_0x3febbd(0x245)],'to',_0x24a5c7[_0x3febbd(0x3fc)],_0x3febbd(0x1f4),_0x24a5c7['yZHUM']],'audio_url':_0x24a5c7[_0x3febbd(0x2f7)]}]},_0x313427[_0x3febbd(0x480)]={'game_code':_0x24a5c7[_0x3febbd(0x209)],'game_id':_0x24a5c7[_0x3febbd(0x333)],'data':[{'id':_0x24a5c7[_0x3febbd(0x345)],'sentence':_0x24a5c7[_0x3febbd(0x340)],'parts':['My',_0x24a5c7[_0x3febbd(0x279)],_0x24a5c7[_0x3febbd(0x4e2)],_0x24a5c7[_0x3febbd(0x424)],'in',_0x24a5c7[_0x3febbd(0x3b0)],_0x24a5c7[_0x3febbd(0x2e7)]],'answer':['My',_0x24a5c7['YhzCy'],_0x24a5c7['QfNiN'],'football','in',_0x24a5c7[_0x3febbd(0x3b0)],_0x24a5c7['nHhPk']],'audio_url':_0x3febbd(0x208)+_0x3febbd(0x437)+_0x3febbd(0x283)+_0x3febbd(0x35d)}]},_0x313427[_0x3febbd(0x243)]={'game_code':_0x24a5c7['LknAV'],'game_id':_0x24a5c7['avWyG'],'data':[{'id':_0x24a5c7['vsRhn'],'sentence':_0x24a5c7[_0x3febbd(0x29a)],'parts':[_0x24a5c7[_0x3febbd(0x46d)],_0x3febbd(0x4ab),_0x24a5c7['DOQPy'],_0x24a5c7['WIsbn'],_0x24a5c7[_0x3febbd(0x39a)],_0x24a5c7[_0x3febbd(0x332)],_0x24a5c7[_0x3febbd(0x3b0)],_0x24a5c7[_0x3febbd(0x2ea)],_0x24a5c7[_0x3febbd(0x3c4)]],'answer':[_0x24a5c7[_0x3febbd(0x46d)],_0x24a5c7['YsLnK'],_0x3febbd(0x27e),_0x24a5c7[_0x3febbd(0x324)],_0x3febbd(0x44c),_0x24a5c7[_0x3febbd(0x332)],_0x24a5c7[_0x3febbd(0x3b0)],_0x24a5c7[_0x3febbd(0x2ea)],_0x24a5c7[_0x3febbd(0x3c4)]],'audio_url':_0x24a5c7[_0x3febbd(0x3a1)]}]},_0x313427['MockData']={'G001':_0x313427[_0x3febbd(0x353)],'G002':_0x313427['MOCK_G002'],'G003':_0x313427[_0x3febbd(0x4b5)],'G004':_0x313427[_0x3febbd(0x487)],'G110':_0x313427[_0x3febbd(0x3b8)],'G111':_0x313427[_0x3febbd(0x45d)],'G112':_0x313427[_0x3febbd(0x2b6)],'G113':_0x313427[_0x3febbd(0x4c1)],'G120':_0x313427[_0x3febbd(0x25d)],'G121':_0x313427[_0x3febbd(0x3cb)],'G122':_0x313427[_0x3febbd(0x480)],'G123':_0x313427[_0x3febbd(0x243)],'G005':_0x313427[_0x3febbd(0x4df)]});},0x3c7(_0x7d555,_0x530c4a){const _0x323861=_0x41c3f4,_0x2eaf0f={'drTtR':function(_0x5ddc0e,_0x15e703){const _0x1da54a=a0_0x3575;return _0x24a5c7[_0x1da54a(0x4ec)](_0x5ddc0e,_0x15e703);},'zZcxr':_0x24a5c7[_0x323861(0x2d0)],'FgEtx':_0x323861(0x2d2)},_0x311c3c={};_0x311c3c['value']=!0x0,(Object[_0x323861(0x1ea)+_0x323861(0x41e)](_0x530c4a,_0x24a5c7[_0x323861(0x360)],_0x311c3c),_0x530c4a[_0x323861(0x3ce)+'E_TYPES']=void 0x0,_0x530c4a[_0x323861(0x2ee)+_0x323861(0x48a)]=function(_0x435803,_0xc0ab2b,_0x106528){return{'type':_0x435803,'payload':_0xc0ab2b,'timestamp':Date['now'](),'request_id':_0x106528};},_0x530c4a[_0x323861(0x210)+'ge']=function(_0x44bc08){const _0x21f0c1=_0x323861;if(_0x24a5c7['dfMjy'](_0x21f0c1(0x4e0),_0x21f0c1(0x4e0))){const _0x2b420a={'PdtEQ':function(_0x5d90f0,_0xbc76e4){return _0x2eaf0f['drTtR'](_0x5d90f0,_0xbc76e4);},'nipNf':_0x2eaf0f[_0x21f0c1(0x431)],'XLPDM':_0x2eaf0f['FgEtx'],'Zgaiv':function(_0x4f2a2f,_0x1e4287){return _0x4f2a2f(_0x1e4287);}};return _0x310f66['map'](_0x4f3b88=>{const _0x8bf309=_0x21f0c1,_0x38e630=(_0x4f3b88[_0x8bf309(0x2db)]||[])[_0x8bf309(0x3b9)](_0x213e0b=>{const _0x4e1d87=_0x8bf309;if(_0x2b420a[_0x4e1d87(0x343)](_0x2b420a[_0x4e1d87(0x4b1)],typeof _0x213e0b))return{'audio':_0x213e0b};if(_0x213e0b&&_0x2b420a[_0x4e1d87(0x228)]==typeof _0x213e0b){const _0x2d53d4=_0x213e0b[_0x4e1d87(0x4d9)]||_0x213e0b['audio_url']||'';return{'audio':_0x2b420a[_0x4e1d87(0x2bb)](_0x2d4630,_0x2d53d4)};}return{'audio':_0x2b420a[_0x4e1d87(0x2bb)](_0xab4520,_0x213e0b??'')};});_0x33a05a(_0x38e630);const _0x2e0320=_0x38e630[_0x8bf309(0x3b9)](_0x558bd1=>_0x24ff8f(_0x558bd1[_0x8bf309(0x4d9)]??'')),_0x366162={};return _0x366162['id']=_0x4f3b88['id'],_0x366162[_0x8bf309(0x49d)]=_0x4f3b88['question'],_0x366162['options']=_0x38e630,_0x366162[_0x8bf309(0x3ab)+_0x8bf309(0x28d)]=_0x2e0320,_0x366162;});}else return _0x44bc08&&_0x24a5c7[_0x21f0c1(0x4ec)](_0x24a5c7[_0x21f0c1(0x231)],typeof _0x44bc08)&&_0x24a5c7[_0x21f0c1(0x4bf)](_0x21f0c1(0x307),_0x44bc08)&&Object['values'](_0x530c4a['SDK_MESSAG'+'E_TYPES'])[_0x21f0c1(0x216)](_0x44bc08[_0x21f0c1(0x307)]);},_0x530c4a[_0x323861(0x3ce)+_0x323861(0x483)]={'SDK_INIT':_0x323861(0x3c1),'SDK_PUSH_DATA':_0x24a5c7[_0x323861(0x3a9)],'SDK_CHECK_ANSWER':_0x24a5c7['elRUi'],'SDK_GET_RESULT':_0x24a5c7[_0x323861(0x235)],'SDK_RETRY_SYNC':_0x323861(0x445)+_0x323861(0x1f0),'SDK_READY':_0x24a5c7['FOdDt'],'SDK_DATA_READY':'SDK_DATA_R'+_0x323861(0x3b3),'SDK_ANSWER_RESULT':_0x323861(0x2dc)+_0x323861(0x4ca),'SDK_SYNC_STATUS':_0x323861(0x1f7)+_0x323861(0x221),'SDK_SYNC_ERROR':_0x24a5c7[_0x323861(0x2e1)],'SDK_FINAL_RESULT':_0x24a5c7[_0x323861(0x207)],'SDK_ERROR':_0x24a5c7[_0x323861(0x455)]});}},_0xe5532d={};return function _0xaf4d95(_0x1a52c9){const _0x5bd511=_0x41c3f4;if(_0x24a5c7[_0x5bd511(0x20d)](_0x24a5c7[_0x5bd511(0x379)],'RSLiT')){var _0x5ac40e=_0xe5532d[_0x1a52c9];if(void 0x0!==_0x5ac40e)return _0x5ac40e[_0x5bd511(0x206)];const _0x4a7eec={};_0x4a7eec[_0x5bd511(0x206)]={};var _0x3ca62f=_0xe5532d[_0x1a52c9]=_0x4a7eec;return _0x4eba57[_0x1a52c9]['call'](_0x3ca62f[_0x5bd511(0x206)],_0x3ca62f,_0x3ca62f['exports'],_0xaf4d95),_0x3ca62f[_0x5bd511(0x206)];}else{const _0x11ff19=_0x454edb[_0x5bd511(0x3f0)]||_0x598c62['parts']||[],_0x297726=_0x250653[_0x5bd511(0x3db)+_0x5bd511(0x409)]||0x0,_0x5cfc41={};_0x5cfc41[_0x5bd511(0x3a0)]=_0x1228a2[_0x5bd511(0x3a0)];if(_0x24a5c7['AlPMy'](0x0,_0x297726)||_0x24a5c7[_0x5bd511(0x4b4)](0x0,_0x11ff19[_0x5bd511(0x24e)]))return{'id':_0x453596['id'],'question':[..._0x11ff19],'options':[],..._0x425b9d['audio_url']&&_0x5cfc41};const _0x1f053e={};_0x1f053e[_0x5bd511(0x24e)]=_0x11ff19['length'];const _0x1e2064=_0x4ed4e9[_0x5bd511(0x443)](_0x1f053e,(_0x407b8f,_0x45250c)=>_0x45250c),_0x45379c=new _0x4cb8a9(),_0x34ffb7=_0x2d7aec[_0x5bd511(0x1f8)](_0x297726,_0x11ff19[_0x5bd511(0x24e)]);for(;_0x24a5c7[_0x5bd511(0x476)](_0x45379c[_0x5bd511(0x475)],_0x34ffb7);){const _0x4ed91a=_0x419593[_0x5bd511(0x2e9)](_0x24a5c7[_0x5bd511(0x256)](_0x3d1947[_0x5bd511(0x1d8)](),_0x1e2064['length'])),_0x41ea4c=_0x1e2064[_0x4ed91a];_0x45379c['add'](_0x41ea4c),_0x1e2064[_0x5bd511(0x468)](_0x4ed91a,0x1);}const _0x4a1861=_0x11ff19[_0x5bd511(0x3b9)]((_0x50f5c2,_0x4dd1bc)=>_0x45379c[_0x5bd511(0x391)](_0x4dd1bc)?'':_0x313ed5(_0x50f5c2)),_0x3eec92=_0x281c6c[_0x5bd511(0x443)](_0x45379c)[_0x5bd511(0x3b9)](_0x475c07=>_0x4d4b7b(_0x11ff19[_0x475c07]));_0x24a5c7[_0x5bd511(0x4c5)](_0x391626,_0x3eec92);const _0x265e1d={};_0x265e1d['id']=_0x17dcd2['id'],_0x265e1d[_0x5bd511(0x49d)]=_0x4a1861,_0x265e1d[_0x5bd511(0x2db)]=_0x3eec92,_0x265e1d[_0x5bd511(0x3ab)+'Options']=[..._0x3eec92];const _0x6bd5ba=_0x265e1d;return _0xaeffee[_0x5bd511(0x3a0)]&&(_0x6bd5ba[_0x5bd511(0x3a0)]=_0x597125[_0x5bd511(0x3a0)]),_0x6bd5ba;}}(0x23e);})())));
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts b/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts
deleted file mode 100644
index d8546a0..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * SDK Iframe Message Types
- * Shared types cho SDK Iframe và Game Bridge
- */
-export declare const SDK_MESSAGE_TYPES: {
- readonly SDK_INIT: "SDK_INIT";
- readonly SDK_PUSH_DATA: "SDK_PUSH_DATA";
- readonly SDK_CHECK_ANSWER: "SDK_CHECK_ANSWER";
- readonly SDK_GET_RESULT: "SDK_GET_RESULT";
- readonly SDK_RETRY_SYNC: "SDK_RETRY_SYNC";
- readonly SDK_READY: "SDK_READY";
- readonly SDK_DATA_READY: "SDK_DATA_READY";
- readonly SDK_ANSWER_RESULT: "SDK_ANSWER_RESULT";
- readonly SDK_SYNC_STATUS: "SDK_SYNC_STATUS";
- readonly SDK_SYNC_ERROR: "SDK_SYNC_ERROR";
- readonly SDK_FINAL_RESULT: "SDK_FINAL_RESULT";
- readonly SDK_ERROR: "SDK_ERROR";
-};
-export type SdkMessageType = typeof SDK_MESSAGE_TYPES[keyof typeof SDK_MESSAGE_TYPES];
-/** SDK_INIT - Khởi tạo SDK */
-export interface SdkInitPayload {
- mode: 'preview' | 'live' | 'dev';
- game_code: string;
- assignment_id?: string | number;
- student_id?: string;
- api_base_url?: string;
- auth_token?: string;
-}
-/** SDK_PUSH_DATA - Push data (preview mode) */
-export interface SdkPushDataPayload {
- data: any[];
- completed_question_ids?: Array<{
- id: string;
- result: 0 | 1;
- }>;
-}
-/** SDK_CHECK_ANSWER - Check đáp án */
-export interface SdkCheckAnswerPayload {
- question_id: string;
- choice: any;
- time_spent?: number;
-}
-/** SDK_READY - SDK sẵn sàng */
-export interface SdkReadyPayload {
- mode: 'preview' | 'live' | 'dev';
- game_code: string;
-}
-/** SDK_DATA_READY - Data đã sẵn sàng (sanitized) */
-export interface SdkDataReadyPayload {
- items: any[];
- total_questions: number;
- completed_count: number;
- resume_data?: Array<{
- id: string;
- result: 0 | 1;
- }>;
-}
-/** SDK_ANSWER_RESULT - Kết quả verify local */
-export interface SdkAnswerResultPayload {
- question_id: string;
- correct: boolean;
- score: number;
- synced: boolean;
-}
-/** SDK_SYNC_STATUS - Đã sync server OK */
-export interface SdkSyncStatusPayload {
- question_id: string;
- synced: true;
- server_result?: {
- correct: boolean;
- score: number;
- };
-}
-/** SDK_SYNC_ERROR - Lỗi sync server */
-export interface SdkSyncErrorPayload {
- question_id: string;
- error: string;
- error_code?: number;
- retryable: boolean;
-}
-/** SDK_FINAL_RESULT - Kết quả cuối cùng */
-export interface SdkFinalResultPayload {
- score: number;
- total: number;
- correct: number;
- wrong: number;
- synced: boolean;
- details: Array<{
- question_id: string;
- choice: any;
- correct: boolean;
- synced: boolean;
- time_spent?: number;
- }>;
-}
-/** SDK_ERROR - Lỗi chung */
-export interface SdkErrorPayload {
- code: string;
- message: string;
- details?: any;
-}
-export interface SdkMessage {
- type: SdkMessageType;
- payload: T;
- timestamp: number;
- request_id?: string;
-}
-export declare function createSdkMessage(type: SdkMessageType, payload: T, requestId?: string): SdkMessage;
-export declare function isSdkMessage(data: any): data is SdkMessage;
-//# sourceMappingURL=types.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts.map b/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts.map
deleted file mode 100644
index 2c620b2..0000000
--- a/G102-sequence/sdk/package/dist/sdk-iframe/types.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sdk-iframe/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAgBpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAMtF,8BAA8B;AAC9B,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,sBAAsB,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC;CACjE;AAED,sCAAsC;AACtC,MAAM,WAAW,qBAAqB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,+BAA+B;AAC/B,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC;CACtD;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,IAAI,CAAC;IACb,aAAa,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,GAAG,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;CACN;AAED,4BAA4B;AAC5B,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,GAAG,CAAC;CACjB;AAMD,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,GAAG;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAOvG;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,UAAU,CAE1D"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sena-game-sdk.js b/G102-sequence/sdk/package/dist/sena-game-sdk.js
deleted file mode 100644
index fdb40c3..0000000
--- a/G102-sequence/sdk/package/dist/sena-game-sdk.js
+++ /dev/null
@@ -1,2 +0,0 @@
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SenaGameSDK=t():e.SenaGameSDK=t()}(Object("undefined"!=typeof self?self:this),()=>(()=>{"use strict";var e={815(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SenaGameSDK=void 0;const s={iframePath:"../sdk-iframe/index.html",mode:"preview",gameCode:"",debug:!1,timeout:1e4,iframeStyle:"position:fixed;width:1px;height:1px;left:-9999px;border:none;"};class i{constructor(e){this.iframe=null,this.isReady=!1,this.isDataReady=!1,this.pendingMessages=[],this.initResolver=null,this.timeoutId=null,this.config={...s,...e};const t=window._sena_game_sdk_instance;t&&"function"==typeof t.destroy&&t.destroy(),window._sena_game_sdk_instance=this,this.initPromise=new Promise((e,t)=>{this.initResolver={resolve:e,reject:t}}),this._handleMessage=this._handleMessage.bind(this),this._init()}pushData(e){let t=[];Array.isArray(e)?t=e:e&&Array.isArray(e.items)?t=e.items:e&&Array.isArray(e.data)?t=e.data:e&&e.items&&"object"==typeof e.items?t=[e.items]:e&&e.data&&"object"==typeof e.data&&(t=[e.data]);const s={data:t,completed_question_ids:e&&e.completed_question_ids||[]};this._send("SDK_PUSH_DATA",s)}submitAnswer(e){const t={question_id:e.questionId,choice:e.selectedAnswer,time_spent:e.timeSpent??0};this._send("SDK_CHECK_ANSWER",t)}completeGame(){this._send("SDK_COMPLETE_GAME",{})}getStatus(){this._send("SDK_GET_STATUS",{})}async ready(){return this.isReady?this:this.initPromise}get sdkReady(){return this.isReady}get dataReady(){return this.isDataReady}destroy(){window.removeEventListener("message",this._handleMessage),this.timeoutId&&clearTimeout(this.timeoutId),this.iframe&&this.iframe.parentNode&&this.iframe.parentNode.removeChild(this.iframe),window.removeEventListener("message",this._handleMessage),this.isReady=!1,this._log("SDK destroyed")}_init(){this._log("Initializing SenaGameSDK..."),window.addEventListener("message",this._handleMessage),this._createIframe(),this.timeoutId=setTimeout(()=>{if(!this.isReady){const e=new Error("SDK initialization timeout");this._error(e),this.initResolver&&this.initResolver.reject(e)}},this.config.timeout)}_createIframe(){this.iframe=document.createElement("iframe"),this.iframe.id="sena-game-sdk-iframe",this.iframe.src=this.config.iframePath,this.iframe.style.cssText=this.config.iframeStyle||"",this.iframe.onload=()=>{this._log("Iframe loaded, sending INIT..."),setTimeout(()=>{this._send("SDK_INIT",{mode:this.config.mode,game_code:this.config.gameCode})},100)},this.iframe.onerror=()=>{this._error(new Error("Failed to load SDK iframe"))},document.body.appendChild(this.iframe),this._log(`Iframe created: ${this.config.iframePath}`)}_send(e,t){if(!this.iframe||!this.iframe.contentWindow)return this._log(`Queuing message: ${e}`,"warn"),void this.pendingMessages.push({type:e,payload:t});const s={type:e,payload:t,timestamp:Date.now()};this._log(`→ ${e}`,"send"),this.iframe.contentWindow.postMessage(s,"*")}_handleMessage(e){const t=e.data;if(t&&t.type&&t.type.startsWith("SDK_"))switch(this._log(`← ${t.type}`,"recv"),t.type){case"SDK_READY":this._onSDKReady();break;case"SDK_DATA_READY":this._onDataReady(t.payload);break;case"SDK_ANSWER_RESULT":this._onAnswerResult(t.payload);break;case"SDK_GAME_COMPLETE":this._onGameComplete(t.payload);break;case"SDK_SESSION_STARTED":this._onSessionStart(t.payload);break;case"SDK_ERROR":this._error(new Error(t.payload?.message||"SDK Error"))}}_onSDKReady(){for(this.isReady=!0,this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null);this.pendingMessages.length>0;){const e=this.pendingMessages.shift();e&&this._send(e.type,e.payload)}this.config.onReady&&this.config.onReady(this),this.initResolver&&this.initResolver.resolve(this),this._log("✅ SDK Ready!")}_onDataReady(e){this.isDataReady=!0;const t={items:e.items||[],totalQuestions:e.total_questions||e.totalQuestions||0,completedCount:e.completed_count||e.completedCount||0,resumeData:e.resume_data||e.resumeData||[]};this.config.onDataReady&&this.config.onDataReady(t),this._log(`✅ Data Ready: ${t.items.length} items`)}_onAnswerResult(e){const t={questionId:e.question_id||e.questionId,isCorrect:void 0!==e.correct?e.correct:e.isCorrect,correctAnswer:e.correct_answer||e.correctAnswer||"",score:e.score||0,currentScore:e.current_score||e.currentScore||0,totalAnswered:e.total_answered||e.totalAnswered||0};this.config.onAnswerResult&&this.config.onAnswerResult(t)}_onGameComplete(e){const t={success:void 0===e.success||e.success,finalScore:void 0!==e.score?e.score:e.finalScore||0,correctCount:void 0!==e.correct?e.correct:e.correctCount||0,totalQuestions:void 0!==e.total?e.total:e.totalQuestions||0,wrongCount:void 0!==e.wrong?e.wrong:e.wrongCount||0,total:e.total||0};this.config.onGameComplete&&this.config.onGameComplete(t)}_onSessionStart(e){const t={assignmentId:e.assignment_id||e.assignmentId,userId:e.student_id||e.userId,gameId:e.game_code||e.gameId,startedAt:e.started_at||e.startedAt||(new Date).toISOString()};this.config.onSessionStart&&this.config.onSessionStart(t)}_error(e){this._log(`❌ Error: ${e.message}`,"error"),this.config.onError&&this.config.onError(e)}_log(e,t="info"){if(!this.config.debug)return;const s={info:"color: #888",send:"color: #ff0",recv:"color: #0f0",warn:"color: #fa0",error:"color: #f00"};console.log(`%c[SenaGameSDK] ${e}`,s[t]||s.info)}}t.SenaGameSDK=i,i.VERSION="1.0.0","undefined"!=typeof window&&(window.SenaGameSDK=i),t.default=i}},t={};function s(i){var o=t[i];if(void 0!==o)return o.exports;var a=t[i]={exports:{}};return e[i](a,a.exports,s),a.exports}var i={};return(()=>{var e=i;e.default=void 0;s(815);var t=s(815);Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.SenaGameSDK}})})(),i.default})());
-//# sourceMappingURL=sena-game-sdk.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/sena-game-sdk.js.map b/G102-sequence/sdk/package/dist/sena-game-sdk.js.map
deleted file mode 100644
index 03a14c5..0000000
--- a/G102-sequence/sdk/package/dist/sena-game-sdk.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"sena-game-sdk.js","mappings":"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","sources":["webpack://SenaGameSDK/webpack/universalModuleDefinition","webpack://SenaGameSDK/./src/loader/SenaGameSDK.ts","webpack://SenaGameSDK/webpack/bootstrap","webpack://SenaGameSDK/./src/loader/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SenaGameSDK\"] = factory();\n\telse\n\t\troot[\"SenaGameSDK\"] = factory();\n})(Object(typeof self !== \"undefined\" ? self : this), () => {\nreturn ","/**\r\n * SenaGame SDK Loader\r\n * \r\n * Ready-to-use interface for game developers.\r\n * Handles SDK iframe creation, communication, and lifecycle.\r\n * \r\n * Usage:\r\n * ```html\r\n * \r\n * \r\n * ```\r\n * \r\n * @version 1.0.0\r\n */\r\n\r\n// ========================================\r\n// TYPES\r\n// ========================================\r\n\r\nexport interface SenaGameConfig {\r\n /** Path to SDK iframe HTML file (can be versioned) */\r\n iframePath: string;\r\n /** Game mode: 'live' | 'preview' */\r\n mode: 'live' | 'preview';\r\n /** Game code for identification */\r\n gameCode: string;\r\n /** Enable debug logging */\r\n debug?: boolean;\r\n /** Timeout for SDK initialization (ms) */\r\n timeout?: number;\r\n /** Custom iframe style */\r\n iframeStyle?: string;\r\n\r\n // Callbacks\r\n onReady?: (sdk: SenaGameSDK) => void;\r\n onDataReady?: (payload: DataReadyPayload) => void;\r\n onAnswerResult?: (result: AnswerResultPayload) => void;\r\n onGameComplete?: (result: GameCompletePayload) => void;\r\n onSessionStart?: (session: SessionStartPayload) => void;\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport interface GameItem {\r\n id: string;\r\n question: string;\r\n options?: string[];\r\n answer?: string | number;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface GameData {\r\n items: GameItem[];\r\n [key: string]: any;\r\n}\r\n\r\nexport interface AnswerPayload {\r\n questionId: string;\r\n selectedAnswer: string | number | string[];\r\n timeSpent?: number;\r\n}\r\n\r\nexport interface DataReadyPayload {\r\n items: GameItem[];\r\n totalQuestions: number;\r\n completedCount: number;\r\n resumeData?: Array<{ id: string; result: 0 | 1 }>;\r\n}\r\n\r\nexport interface AnswerResultPayload {\r\n questionId: string;\r\n isCorrect: boolean;\r\n correctAnswer: string | number;\r\n score: number;\r\n currentScore: number;\r\n totalAnswered: number;\r\n}\r\n\r\nexport interface GameCompletePayload {\r\n success: boolean;\r\n finalScore: number;\r\n correctCount: number;\r\n totalQuestions: number;\r\n wrongCount: number;\r\n total: number;\r\n}\r\n\r\nexport interface SessionStartPayload {\r\n assignmentId: number;\r\n userId: string;\r\n gameId: string;\r\n startedAt: string;\r\n}\r\n\r\n// ========================================\r\n// MESSAGE TYPES (matching SDK)\r\n// ========================================\r\nconst MSG = {\r\n // Outgoing (Game → SDK)\r\n INIT: 'SDK_INIT',\r\n PUSH_DATA: 'SDK_PUSH_DATA',\r\n SUBMIT_ANSWER: 'SDK_CHECK_ANSWER',\r\n COMPLETE_GAME: 'SDK_COMPLETE_GAME',\r\n GET_STATUS: 'SDK_GET_STATUS',\r\n\r\n // Incoming (SDK → Game)\r\n READY: 'SDK_READY',\r\n DATA_READY: 'SDK_DATA_READY',\r\n ANSWER_RESULT: 'SDK_ANSWER_RESULT',\r\n GAME_COMPLETE: 'SDK_GAME_COMPLETE',\r\n SESSION_STARTED: 'SDK_SESSION_STARTED',\r\n STATUS: 'SDK_STATUS',\r\n ERROR: 'SDK_ERROR',\r\n} as const;\r\n\r\n// ========================================\r\n// DEFAULT CONFIG\r\n// ========================================\r\nconst DEFAULT_CONFIG: Partial = {\r\n iframePath: '../sdk-iframe/index.html',\r\n mode: 'preview',\r\n gameCode: '',\r\n debug: false,\r\n timeout: 10000,\r\n iframeStyle: 'position:fixed;width:1px;height:1px;left:-9999px;border:none;',\r\n};\r\n\r\n// ========================================\r\n// SENA GAME SDK CLASS\r\n// ========================================\r\nexport class SenaGameSDK {\r\n private config: SenaGameConfig;\r\n private iframe: HTMLIFrameElement | null = null;\r\n private isReady: boolean = false;\r\n private isDataReady: boolean = false;\r\n private pendingMessages: Array<{ type: string; payload: any }> = [];\r\n private initPromise: Promise;\r\n private initResolver: { resolve: (sdk: SenaGameSDK) => void; reject: (error: Error) => void } | null = null;\r\n private timeoutId: ReturnType | null = null;\r\n\r\n /** SDK version */\r\n static readonly VERSION = '1.0.0';\r\n\r\n constructor(config: SenaGameConfig) {\r\n this.config = { ...DEFAULT_CONFIG, ...config } as SenaGameConfig;\r\n\r\n // --- CLEANUP OLD LISTENERS ---\r\n // Tránh trường hợp init SDK nhiều lần bị trùng listener cũ\r\n const oldSDK = (window as any)._sena_game_sdk_instance;\r\n if (oldSDK && typeof oldSDK.destroy === 'function') {\r\n oldSDK.destroy();\r\n }\r\n (window as any)._sena_game_sdk_instance = this;\r\n\r\n // Create promise for ready state\r\n this.initPromise = new Promise((resolve, reject) => {\r\n this.initResolver = { resolve, reject };\r\n });\r\n\r\n // Bind methods\r\n this._handleMessage = this._handleMessage.bind(this);\r\n\r\n // Auto-initialize\r\n this._init();\r\n }\r\n\r\n // ----------------------------------------\r\n // PUBLIC API\r\n // ----------------------------------------\r\n\r\n /**\r\n * Push game data to SDK\r\n */\r\n pushData(data: any): void {\r\n // Safe extraction of the array\r\n let itemsArray: any[] = [];\r\n\r\n if (Array.isArray(data)) {\r\n itemsArray = data;\r\n } else if (data && Array.isArray(data.items)) {\r\n itemsArray = data.items;\r\n } else if (data && Array.isArray(data.data)) {\r\n itemsArray = data.data;\r\n } else if (data && data.items && typeof data.items === 'object') {\r\n itemsArray = [data.items];\r\n } else if (data && data.data && typeof data.data === 'object') {\r\n itemsArray = [data.data];\r\n }\r\n\r\n // Transform to SDK iframe internal format\r\n const payload = {\r\n data: itemsArray,\r\n completed_question_ids: (data && data.completed_question_ids) || []\r\n };\r\n\r\n this._send(MSG.PUSH_DATA, payload);\r\n }\r\n\r\n /**\r\n * Submit an answer\r\n */\r\n submitAnswer(answer: AnswerPayload): void {\r\n // Transform to SDK iframe format\r\n const payload = {\r\n question_id: answer.questionId,\r\n choice: answer.selectedAnswer,\r\n time_spent: answer.timeSpent ?? 0\r\n };\r\n this._send(MSG.SUBMIT_ANSWER, payload);\r\n }\r\n\r\n /**\r\n * Complete the game\r\n */\r\n completeGame(): void {\r\n this._send(MSG.COMPLETE_GAME, {});\r\n }\r\n\r\n /**\r\n * Get current status\r\n */\r\n getStatus(): void {\r\n this._send(MSG.GET_STATUS, {});\r\n }\r\n\r\n /**\r\n * Wait for SDK to be ready\r\n */\r\n async ready(): Promise {\r\n if (this.isReady) return this;\r\n return this.initPromise;\r\n }\r\n\r\n /**\r\n * Check if SDK is ready\r\n */\r\n get sdkReady(): boolean {\r\n return this.isReady;\r\n }\r\n\r\n /**\r\n * Check if data is ready\r\n */\r\n get dataReady(): boolean {\r\n return this.isDataReady;\r\n }\r\n\r\n /**\r\n * Destroy the SDK instance\r\n */\r\n destroy(): void {\r\n window.removeEventListener('message', this._handleMessage);\r\n if (this.timeoutId) {\r\n clearTimeout(this.timeoutId);\r\n }\r\n if (this.iframe && this.iframe.parentNode) {\r\n this.iframe.parentNode.removeChild(this.iframe);\r\n }\r\n window.removeEventListener('message', this._handleMessage);\r\n this.isReady = false;\r\n this._log('SDK destroyed');\r\n }\r\n\r\n // ----------------------------------------\r\n // PRIVATE METHODS\r\n // ----------------------------------------\r\n\r\n private _init(): void {\r\n this._log('Initializing SenaGameSDK...');\r\n\r\n // Setup message listener\r\n window.addEventListener('message', this._handleMessage);\r\n\r\n // Create iframe\r\n this._createIframe();\r\n\r\n // Setup timeout\r\n this.timeoutId = setTimeout(() => {\r\n if (!this.isReady) {\r\n const error = new Error('SDK initialization timeout');\r\n this._error(error);\r\n if (this.initResolver) {\r\n this.initResolver.reject(error);\r\n }\r\n }\r\n }, this.config.timeout);\r\n }\r\n\r\n private _createIframe(): void {\r\n this.iframe = document.createElement('iframe');\r\n this.iframe.id = 'sena-game-sdk-iframe';\r\n this.iframe.src = this.config.iframePath;\r\n this.iframe.style.cssText = this.config.iframeStyle || '';\r\n\r\n this.iframe.onload = () => {\r\n this._log('Iframe loaded, sending INIT...');\r\n setTimeout(() => {\r\n this._send(MSG.INIT, {\r\n mode: this.config.mode,\r\n game_code: this.config.gameCode,\r\n });\r\n }, 100);\r\n };\r\n\r\n this.iframe.onerror = () => {\r\n this._error(new Error('Failed to load SDK iframe'));\r\n };\r\n\r\n document.body.appendChild(this.iframe);\r\n this._log(`Iframe created: ${this.config.iframePath}`);\r\n }\r\n\r\n private _send(type: string, payload: any): void {\r\n if (!this.iframe || !this.iframe.contentWindow) {\r\n this._log(`Queuing message: ${type}`, 'warn');\r\n this.pendingMessages.push({ type, payload });\r\n return;\r\n }\r\n\r\n const message = { type, payload, timestamp: Date.now() };\r\n this._log(`→ ${type}`, 'send');\r\n this.iframe.contentWindow.postMessage(message, '*');\r\n }\r\n\r\n private _handleMessage(event: MessageEvent): void {\r\n const data = event.data;\r\n if (!data || !data.type) return;\r\n\r\n // Only process SDK messages\r\n if (!data.type.startsWith('SDK_')) return;\r\n\r\n this._log(`← ${data.type}`, 'recv');\r\n\r\n switch (data.type) {\r\n case MSG.READY:\r\n this._onSDKReady();\r\n break;\r\n\r\n case MSG.DATA_READY:\r\n this._onDataReady(data.payload);\r\n break;\r\n\r\n case MSG.ANSWER_RESULT:\r\n this._onAnswerResult(data.payload);\r\n break;\r\n\r\n case MSG.GAME_COMPLETE:\r\n this._onGameComplete(data.payload);\r\n break;\r\n\r\n case MSG.SESSION_STARTED:\r\n this._onSessionStart(data.payload);\r\n break;\r\n\r\n case MSG.ERROR:\r\n this._error(new Error(data.payload?.message || 'SDK Error'));\r\n break;\r\n }\r\n }\r\n\r\n private _onSDKReady(): void {\r\n this.isReady = true;\r\n\r\n if (this.timeoutId) {\r\n clearTimeout(this.timeoutId);\r\n this.timeoutId = null;\r\n }\r\n\r\n // Flush pending messages\r\n while (this.pendingMessages.length > 0) {\r\n const msg = this.pendingMessages.shift();\r\n if (msg) {\r\n this._send(msg.type, msg.payload);\r\n }\r\n }\r\n\r\n // Callback\r\n if (this.config.onReady) {\r\n this.config.onReady(this);\r\n }\r\n\r\n // Resolve promise\r\n if (this.initResolver) {\r\n this.initResolver.resolve(this);\r\n }\r\n\r\n this._log('✅ SDK Ready!');\r\n }\r\n\r\n private _onDataReady(payload: any): void {\r\n this.isDataReady = true;\r\n\r\n // Normalize payload to camelCase\r\n const normalized: DataReadyPayload = {\r\n items: payload.items || [],\r\n totalQuestions: payload.total_questions || payload.totalQuestions || 0,\r\n completedCount: payload.completed_count || payload.completedCount || 0,\r\n resumeData: payload.resume_data || payload.resumeData || []\r\n };\r\n\r\n if (this.config.onDataReady) {\r\n this.config.onDataReady(normalized);\r\n }\r\n\r\n this._log(`✅ Data Ready: ${normalized.items.length} items`);\r\n }\r\n\r\n private _onAnswerResult(payload: any): void {\r\n const normalized: AnswerResultPayload = {\r\n questionId: payload.question_id || payload.questionId,\r\n isCorrect: payload.correct !== undefined ? payload.correct : payload.isCorrect,\r\n correctAnswer: payload.correct_answer || payload.correctAnswer || '',\r\n score: payload.score || 0,\r\n currentScore: payload.current_score || payload.currentScore || 0,\r\n totalAnswered: payload.total_answered || payload.totalAnswered || 0\r\n };\r\n if (this.config.onAnswerResult) {\r\n this.config.onAnswerResult(normalized);\r\n }\r\n }\r\n\r\n private _onGameComplete(payload: any): void {\r\n const normalized: GameCompletePayload = {\r\n success: payload.success !== undefined ? payload.success : true,\r\n finalScore: payload.score !== undefined ? payload.score : (payload.finalScore || 0),\r\n correctCount: payload.correct !== undefined ? payload.correct : (payload.correctCount || 0),\r\n totalQuestions: payload.total !== undefined ? payload.total : (payload.totalQuestions || 0),\r\n wrongCount: payload.wrong !== undefined ? payload.wrong : (payload.wrongCount || 0),\r\n total: payload.total || 0\r\n };\r\n if (this.config.onGameComplete) {\r\n this.config.onGameComplete(normalized);\r\n }\r\n }\r\n\r\n private _onSessionStart(payload: any): void {\r\n const normalized: SessionStartPayload = {\r\n assignmentId: payload.assignment_id || payload.assignmentId,\r\n userId: payload.student_id || payload.userId,\r\n gameId: payload.game_code || payload.gameId,\r\n startedAt: payload.started_at || payload.startedAt || new Date().toISOString()\r\n };\r\n if (this.config.onSessionStart) {\r\n this.config.onSessionStart(normalized);\r\n }\r\n }\r\n\r\n private _error(error: Error): void {\r\n this._log(`❌ Error: ${error.message}`, 'error');\r\n\r\n if (this.config.onError) {\r\n this.config.onError(error);\r\n }\r\n }\r\n\r\n private _log(message: string, type: 'info' | 'send' | 'recv' | 'warn' | 'error' = 'info'): void {\r\n if (!this.config.debug) return;\r\n\r\n const prefix = '[SenaGameSDK]';\r\n const styles: Record = {\r\n info: 'color: #888',\r\n send: 'color: #ff0',\r\n recv: 'color: #0f0',\r\n warn: 'color: #fa0',\r\n error: 'color: #f00',\r\n };\r\n\r\n console.log(`%c${prefix} ${message}`, styles[type] || styles.info);\r\n }\r\n}\r\n\r\n// ========================================\r\n// EXPORT FOR BROWSER (UMD)\r\n// ========================================\r\nif (typeof window !== 'undefined') {\r\n (window as any).SenaGameSDK = SenaGameSDK;\r\n}\r\n\r\nexport default SenaGameSDK;\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\r\n * SenaGame SDK Loader\r\n * Export all types and classes for game developers\r\n */\r\n\r\nexport {\r\n SenaGameSDK,\r\n type SenaGameConfig,\r\n type GameItem,\r\n type GameData,\r\n type AnswerPayload,\r\n type DataReadyPayload,\r\n type AnswerResultPayload,\r\n type GameCompletePayload,\r\n type SessionStartPayload,\r\n} from './SenaGameSDK';\r\n\r\nexport { SenaGameSDK as default } from './SenaGameSDK';\r\n"],"names":["root","factory","exports","module","define","amd","Object","self","this","DEFAULT_CONFIG","iframePath","mode","gameCode","debug","timeout","iframeStyle","SenaGameSDK","constructor","config","iframe","isReady","isDataReady","pendingMessages","initResolver","timeoutId","oldSDK","window","_sena_game_sdk_instance","destroy","initPromise","Promise","resolve","reject","_handleMessage","bind","_init","pushData","data","itemsArray","Array","isArray","items","payload","completed_question_ids","_send","submitAnswer","answer","question_id","questionId","choice","selectedAnswer","time_spent","timeSpent","completeGame","getStatus","ready","sdkReady","dataReady","removeEventListener","clearTimeout","parentNode","removeChild","_log","addEventListener","_createIframe","setTimeout","error","Error","_error","document","createElement","id","src","style","cssText","onload","game_code","onerror","body","appendChild","type","contentWindow","push","message","timestamp","Date","now","postMessage","event","startsWith","_onSDKReady","_onDataReady","_onAnswerResult","_onGameComplete","_onSessionStart","length","msg","shift","onReady","normalized","totalQuestions","total_questions","completedCount","completed_count","resumeData","resume_data","onDataReady","isCorrect","undefined","correct","correctAnswer","correct_answer","score","currentScore","current_score","totalAnswered","total_answered","onAnswerResult","success","finalScore","correctCount","total","wrongCount","wrong","onGameComplete","assignmentId","assignment_id","userId","student_id","gameId","startedAt","started_at","toISOString","onSessionStart","onError","styles","info","send","recv","warn","console","log","VERSION","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__"],"ignoreList":[],"sourceRoot":""}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/types.d.ts b/G102-sequence/sdk/package/dist/types.d.ts
deleted file mode 100644
index 2708e0b..0000000
--- a/G102-sequence/sdk/package/dist/types.d.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Game Iframe SDK - Types Definition
- */
-export declare const MESSAGE_TYPES: {
- readonly SERVER_PUSH_DATA: "SERVER_PUSH_DATA";
- readonly SERVER_PUSH_LEADERBOARD: "SERVER_PUSH_LEADERBOARD";
- readonly GAME_READY: "GAME_READY";
- readonly ANSWER_REPORT: "ANSWER_REPORT";
- readonly FINAL_RESULT: "FINAL_RESULT";
- readonly GET_LEADERBOARD: "GET_LEADERBOARD";
-};
-export type MessageType = typeof MESSAGE_TYPES[keyof typeof MESSAGE_TYPES];
-/**
- * Payload sent in SERVER_PUSH_DATA
- */
-export interface PushDataPayload {
- /** Game ID */
- game_id: string;
- /**
- * List of items - dynamic structure
- */
- data?: any[];
- /** Resume data */
- completed_question_ids?: Array<{
- id: string;
- result: 0 | 1;
- [key: string]: any;
- }>;
- [key: string]: any;
-}
-export interface CompletedQuestionInfo {
- id: string;
- result: 0 | 1;
- [key: string]: any;
-}
-export interface AnswerReportData {
- question_id: string;
- question_index?: number;
- choice: string | number;
- result: 0 | 1;
- time_spent?: number;
- [key: string]: any;
-}
-export interface FinalResultData {
- score: number;
- total: number;
- correct: number;
- wrong: number;
- details?: any[];
- [key: string]: any;
-}
-export interface LeaderboardPlayer {
- rank: number;
- name: string;
- score: number;
- [key: string]: any;
-}
-export interface LeaderboardData {
- top_players: LeaderboardPlayer[];
- user_rank?: LeaderboardPlayer | null;
-}
-export interface GameIframeSDKConfig {
- iframeOrigin: string;
- readyDelay?: number;
- autoSendOnReady?: boolean;
- debug?: boolean;
-}
-export declare const DEFAULT_CONFIG: Required;
-export interface SDKEvents {
- gameReady: void;
- answerReport: AnswerReportData;
- finalResult: FinalResultData;
- leaderboardRequest: {
- top: number;
- };
- error: {
- message: string;
- error?: any;
- };
- log: {
- level: string;
- message: string;
- data?: any;
- };
-}
-export type SDKEventName = keyof SDKEvents;
-export type SDKEventHandler = (data: SDKEvents[T]) => void;
-//# sourceMappingURL=types.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/types.d.ts.map b/G102-sequence/sdk/package/dist/types.d.ts.map
deleted file mode 100644
index 26f41bc..0000000
--- a/G102-sequence/sdk/package/dist/types.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,aAAa;;;;;;;CAUhB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAM3E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,cAAc;IACd,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IAEb,kBAAkB;IAClB,sBAAsB,CAAC,EAAE,KAAK,CAAC;QAC3B,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC,CAAC;IAEH,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAMD,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAMD,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACxC;AAMD,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,mBAAmB,CAKxD,CAAC;AAMF,MAAM,WAAW,SAAS;IACtB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,WAAW,EAAE,eAAe,CAAC;IAC7B,kBAAkB,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACxC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;CACvD;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC;AAC3C,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,YAAY,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/types.js b/G102-sequence/sdk/package/dist/types.js
deleted file mode 100644
index ea2e3d4..0000000
--- a/G102-sequence/sdk/package/dist/types.js
+++ /dev/null
@@ -1,26 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - Types Definition
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.DEFAULT_CONFIG = exports.MESSAGE_TYPES = void 0;
-// =============================================================================
-// MESSAGE TYPES
-// =============================================================================
-exports.MESSAGE_TYPES = {
- // Parent → Iframe
- SERVER_PUSH_DATA: 'SERVER_PUSH_DATA',
- SERVER_PUSH_LEADERBOARD: 'SERVER_PUSH_LEADERBOARD',
- // Iframe → Parent
- GAME_READY: 'GAME_READY',
- ANSWER_REPORT: 'ANSWER_REPORT',
- FINAL_RESULT: 'FINAL_RESULT',
- GET_LEADERBOARD: 'GET_LEADERBOARD',
-};
-exports.DEFAULT_CONFIG = {
- iframeOrigin: '*',
- readyDelay: 500,
- autoSendOnReady: true,
- debug: false,
-};
-//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/types.js.map b/G102-sequence/sdk/package/dist/types.js.map
deleted file mode 100644
index 0aa83ce..0000000
--- a/G102-sequence/sdk/package/dist/types.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEnE,QAAA,aAAa,GAAG;IACzB,kBAAkB;IAClB,gBAAgB,EAAE,kBAAkB;IACpC,uBAAuB,EAAE,yBAAyB;IAElD,kBAAkB;IAClB,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,eAAe,EAAE,iBAAiB;CAC5B,CAAC;AAqFE,QAAA,cAAc,GAAkC;IACzD,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,KAAK;CACf,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts b/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts
deleted file mode 100644
index 9e77ecc..0000000
--- a/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Game Iframe SDK - React Hook
- * Custom hook để sử dụng SDK trong React components
- *
- * @example
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk/react';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const {
- * isReady,
- * sendGameData,
- * sendLeaderboard
- * } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onGameReady: () => console.log('Game ready!'),
- * onAnswerReport: (data) => submitToServer(data),
- * onFinalResult: (data) => showResults(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-import { GameIframeSDK } from './GameIframeSDK';
-import { GameIframeSDKConfig, PushDataPayload, LeaderboardData, AnswerReportData, FinalResultData } from './types';
-export interface UseGameIframeSDKOptions extends Omit {
- /**
- * Ref to iframe element
- */
- iframeRef: React.RefObject;
- /**
- * Origin of iframe (required)
- */
- iframeOrigin: string;
- /**
- * Callback when game is ready
- */
- onGameReady?: () => void;
- /**
- * Callback when user answers a question
- */
- onAnswerReport?: (data: AnswerReportData) => void;
- /**
- * Callback when game ends
- */
- onFinalResult?: (data: FinalResultData) => void;
- /**
- * Callback when game requests leaderboard
- */
- onLeaderboardRequest?: (top: number) => void;
- /**
- * Callback for errors
- */
- onError?: (error: {
- message: string;
- error?: any;
- }) => void;
-}
-export interface UseGameIframeSDKReturn {
- /**
- * SDK instance
- */
- sdk: GameIframeSDK | null;
- /**
- * Whether game is ready
- */
- isReady: boolean;
- /**
- * Send game data to iframe
- */
- sendGameData: (data: PushDataPayload) => boolean;
- /**
- * Send leaderboard data
- */
- sendLeaderboard: (data: LeaderboardData) => boolean;
- /**
- * Queue data to send when ready
- */
- queueGameData: (data: PushDataPayload) => void;
- /**
- * Force reload iframe
- */
- reloadIframe: () => boolean;
-}
-export declare function useGameIframeSDK(options: UseGameIframeSDKOptions): UseGameIframeSDKReturn;
-export default useGameIframeSDK;
-//# sourceMappingURL=useGameIframeSDK.d.ts.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts.map b/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts.map
deleted file mode 100644
index 3c5abf5..0000000
--- a/G102-sequence/sdk/package/dist/useGameIframeSDK.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"useGameIframeSDK.d.ts","sourceRoot":"","sources":["../src/useGameIframeSDK.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACH,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EAClB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC;IACtF;;OAEG;IACH,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAE9C;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAEhD;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,sBAAsB;IACnC;;OAEG;IACH,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC;IAEjD;;OAEG;IACH,eAAe,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC;IAEpD;;OAEG;IACH,aAAa,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAE/C;;OAEG;IACH,YAAY,EAAE,MAAM,OAAO,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CA6HzF;AAED,eAAe,gBAAgB,CAAC"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/useGameIframeSDK.js b/G102-sequence/sdk/package/dist/useGameIframeSDK.js
deleted file mode 100644
index 8a52d6a..0000000
--- a/G102-sequence/sdk/package/dist/useGameIframeSDK.js
+++ /dev/null
@@ -1,120 +0,0 @@
-"use strict";
-/**
- * Game Iframe SDK - React Hook
- * Custom hook để sử dụng SDK trong React components
- *
- * @example
- * ```tsx
- * import { useGameIframeSDK } from 'game-iframe-sdk/react';
- *
- * function GamePlayer() {
- * const iframeRef = useRef(null);
- *
- * const {
- * isReady,
- * sendGameData,
- * sendLeaderboard
- * } = useGameIframeSDK({
- * iframeRef,
- * iframeOrigin: 'http://senaai.vn:1357',
- * onGameReady: () => console.log('Game ready!'),
- * onAnswerReport: (data) => submitToServer(data),
- * onFinalResult: (data) => showResults(data),
- * });
- *
- * return ;
- * }
- * ```
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.useGameIframeSDK = useGameIframeSDK;
-const react_1 = require("react");
-const GameIframeSDK_1 = require("./GameIframeSDK");
-function useGameIframeSDK(options) {
- const { iframeRef, iframeOrigin, readyDelay, autoSendOnReady, debug, onGameReady, onAnswerReport, onFinalResult, onLeaderboardRequest, onError, } = options;
- const [isReady, setIsReady] = (0, react_1.useState)(false);
- const sdkRef = (0, react_1.useRef)(null);
- // Use refs for callbacks to avoid re-creating SDK when callbacks change
- const callbacksRef = (0, react_1.useRef)({
- onGameReady,
- onAnswerReport,
- onFinalResult,
- onLeaderboardRequest,
- onError,
- });
- // Update callback refs on each render (no effect re-run)
- callbacksRef.current = {
- onGameReady,
- onAnswerReport,
- onFinalResult,
- onLeaderboardRequest,
- onError,
- };
- // Initialize SDK - only depends on config, NOT callbacks
- (0, react_1.useEffect)(() => {
- const sdk = new GameIframeSDK_1.GameIframeSDK({
- iframeOrigin,
- readyDelay,
- autoSendOnReady,
- debug,
- });
- sdkRef.current = sdk;
- // Subscribe to events using refs (stable references)
- const unsubscribers = [];
- unsubscribers.push(sdk.on('gameReady', () => {
- setIsReady(true);
- callbacksRef.current.onGameReady?.();
- }));
- unsubscribers.push(sdk.on('answerReport', (data) => {
- callbacksRef.current.onAnswerReport?.(data);
- }));
- unsubscribers.push(sdk.on('finalResult', (data) => {
- callbacksRef.current.onFinalResult?.(data);
- }));
- unsubscribers.push(sdk.on('leaderboardRequest', (data) => {
- callbacksRef.current.onLeaderboardRequest?.(data.top || 10);
- }));
- unsubscribers.push(sdk.on('error', (err) => {
- callbacksRef.current.onError?.(err);
- }));
- return () => {
- unsubscribers.forEach((unsub) => unsub());
- sdk.destroy();
- sdkRef.current = null;
- };
- }, [iframeOrigin, readyDelay, autoSendOnReady, debug]); // ✅ No callback deps
- // Sync iframe ref with SDK
- (0, react_1.useEffect)(() => {
- if (sdkRef.current && iframeRef.current) {
- sdkRef.current.setIframe(iframeRef.current);
- }
- }, [iframeRef.current]);
- // Reset ready state when iframe src changes
- (0, react_1.useEffect)(() => {
- setIsReady(false);
- }, [iframeRef.current?.src]);
- // Memoized methods
- const sendGameData = (0, react_1.useCallback)((data) => {
- return sdkRef.current?.sendGameData(data) ?? false;
- }, []);
- const sendLeaderboard = (0, react_1.useCallback)((data) => {
- return sdkRef.current?.sendLeaderboard(data) ?? false;
- }, []);
- const queueGameData = (0, react_1.useCallback)((data) => {
- sdkRef.current?.queueGameData(data);
- }, []);
- const reloadIframe = (0, react_1.useCallback)(() => {
- setIsReady(false);
- return sdkRef.current?.reloadIframe() ?? false;
- }, []);
- return {
- sdk: sdkRef.current,
- isReady,
- sendGameData,
- sendLeaderboard,
- queueGameData,
- reloadIframe,
- };
-}
-exports.default = useGameIframeSDK;
-//# sourceMappingURL=useGameIframeSDK.js.map
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/dist/useGameIframeSDK.js.map b/G102-sequence/sdk/package/dist/useGameIframeSDK.js.map
deleted file mode 100644
index 627df44..0000000
--- a/G102-sequence/sdk/package/dist/useGameIframeSDK.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"useGameIframeSDK.js","sourceRoot":"","sources":["../src/useGameIframeSDK.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/G102-sequence/sdk/package/package.json b/G102-sequence/sdk/package/package.json
deleted file mode 100644
index 92c305f..0000000
--- a/G102-sequence/sdk/package/package.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "name": "game-iframe-sdk",
- "version": "1.1.2",
- "description": "SDK for communicating with game iframes (postMessage protocol)",
- "main": "./dist/index.js",
- "module": "./dist/esm/index.js",
- "types": "./dist/index.d.ts",
- "exports": {
- ".": {
- "import": "./dist/esm/index.js",
- "require": "./dist/index.js",
- "types": "./dist/index.d.ts"
- }
- },
- "files": [
- "dist",
- "README.md"
- ],
- "scripts": {
- "build:iframe": "webpack --config webpack.config.js",
- "build": "tsc && tsc -p tsconfig.esm.json && npm run build:iframe",
- "clean": "rimraf dist",
- "prepublishOnly": "npm run clean && npm run build",
- "typecheck": "tsc --noEmit"
- },
- "keywords": [
- "game",
- "iframe",
- "sdk",
- "postMessage",
- "communication"
- ],
- "author": "Sena AI",
- "license": "MIT",
- "peerDependencies": {
- "react": ">=16.8.0"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- }
- },
- "devDependencies": {
- "@types/node": "^20.10.0",
- "@types/react": "^18.2.0",
- "copy-webpack-plugin": "^13.0.1",
- "html-webpack-plugin": "^5.6.6",
- "rimraf": "^5.0.5",
- "ts-loader": "^9.5.4",
- "typescript": "^5.3.0",
- "webpack": "^5.104.1",
- "webpack-cli": "^6.0.1",
- "webpack-obfuscator": "^3.6.0"
- }
-}
diff --git a/G102-sequence/tdv_sdk.js b/G102-sequence/tdv_sdk.js
deleted file mode 100644
index 2f739f4..0000000
--- a/G102-sequence/tdv_sdk.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * =========================================
- * TDV_SDK – SENTENCE SEQUENCE (G120)
- * Compatible with Construct 2
- * =========================================
- */
-
-var tdv_sdk = {
-
- /* ================= CORE ================= */
- mode: "preview",
- game_code: "G120",
-
- gameData: [],
- currentQuestionIndex: 0,
- currentQuestion: null,
-
- /* ================= QUESTION ================= */
- correctSentence: "",
- correctWords: [],
- currentWords: [],
- blankCount: 1,
-
- /* ================= SLOT ================= */
- placedWords: [],
- blankIndexes: [],
- missingWords: [],
- canSubmit: 0,
-
- /* ================= INIT ================= */
- init: function (config) {
- console.log("✅ tdv_sdk.init called", config);
-
- window.answerResult = -1;
- window.gameState = 0;
-
- // Data được push từ SDK Bridge
- if (window.SDK_GAME_DATA) {
- this.gameData = window.SDK_GAME_DATA;
- }
-
- this.loadQuestions();
- },
-
- /* ================= LOAD QUESTION ================= */
- loadQuestions: function () {
- var q = this.gameData[this.currentQuestionIndex];
- if (!q) {
- console.warn("No question data");
- return;
- }
-
- this.currentQuestion = q;
-
- // Chuẩn G120
- this.correctSentence = q.sentence || "";
- this.correctWords = this.correctSentence.split(/\s+/);
- this.blankCount = q.blank_count || 1;
-
- this.currentWords = [...this.correctWords];
-
- this.resetPlacedWords();
- this.generateBlankIndexes();
- this.generateMissingWords();
-
- console.log("📝 Loaded sentence:", this.correctSentence);
- },
-
- /* ================= SLOT LOGIC ================= */
- resetPlacedWords: function () {
- this.placedWords = new Array(this.correctWords.length).fill("");
- this.canSubmit = 0;
- },
-
- setWordAtSlot: function (word, index) {
- this.placedWords[index] = word;
- this.updateSubmitState();
- },
-
- updateSubmitState: function () {
- var filled = this.blankIndexes.filter(i => this.placedWords[i]).length;
- this.canSubmit = (filled === this.blankIndexes.length) ? 1 : 0;
- },
-
- /* ================= BLANK ================= */
- generateBlankIndexes: function () {
- var pool = [...Array(this.correctWords.length).keys()];
- pool.sort(() => Math.random() - 0.5);
- this.blankIndexes = pool.slice(0, this.blankCount);
- },
-
- generateMissingWords: function () {
- this.missingWords = this.blankIndexes.map(i => this.correctWords[i]);
- },
-
- /* ================= BUILD ================= */
- buildUserSentence: function () {
- var result = [];
- for (var i = 0; i < this.correctWords.length; i++) {
- if (this.blankIndexes.includes(i)) {
- result.push(this.placedWords[i] || "");
- } else {
- result.push(this.correctWords[i]);
- }
- }
- return result.join(" ").replace(/\s+/g, " ").trim();
- },
-
- /* ================= SUBMIT ================= */
- submitAnswer: function () {
- if (this.canSubmit !== 1) return -1;
-
- var userSentence = this.buildUserSentence();
- console.log("📤 SUBMIT:", userSentence);
-
- window.answerResult = (userSentence === this.correctSentence) ? 1 : 0;
- window.gameState = 2;
-
- return window.answerResult;
- },
-
- /* ================= API FOR CONSTRUCT 2 ================= */
- getInstructions: function () {
- return "Drag the missing words to complete the sentence.";
- },
-
- getWordsCount: function () {
- return this.correctWords.length;
- },
-
- getBlankCount: function () {
- return this.blankIndexes.length;
- },
-
- canSubmitAnswer: function () {
- return this.canSubmit;
- },
-
- getCurrentScore: function () {
- return window.answerResult === 1 ? 1 : 0;
- },
-
- getRemainingTime: function () {
- return 0;
- },
-
- getCorrectResultText: function () {
- return this.correctSentence;
- },
-
- forceFinishGame: function () {
- window.gameState = 2;
- },
-
- leaderboard: function () {
- return "";
- }
-};
diff --git a/New-project/appmanifest.json b/G120-sequence/appmanifest.json
similarity index 100%
rename from New-project/appmanifest.json
rename to G120-sequence/appmanifest.json
diff --git a/G102-sequence/c2runtime.js b/G120-sequence/c2runtime.js
similarity index 91%
rename from G102-sequence/c2runtime.js
rename to G120-sequence/c2runtime.js
index 184ecdd..ce2a2fe 100644
--- a/G102-sequence/c2runtime.js
+++ b/G120-sequence/c2runtime.js
@@ -19321,6 +19321,373 @@ cr.plugins_.Function = function(runtime)
}());
;
;
+cr.plugins_.SenaPlugin = function (runtime) {
+ this.runtime = runtime;
+};
+(function () {
+ var pluginProto = cr.plugins_.SenaPlugin.prototype;
+ pluginProto.Type = function (plugin) {
+ this.plugin = plugin;
+ this.runtime = plugin.runtime;
+ };
+ var typeProto = pluginProto.Type.prototype;
+ typeProto.onCreate = function () {
+ };
+ pluginProto.Instance = function (type) {
+ this.type = type;
+ this.runtime = type.runtime;
+ };
+ var instanceProto = pluginProto.Instance.prototype;
+ instanceProto.onCreate = function () {
+ window['SenaTrigger'] = this;
+ this.sdk = null;
+ this.isPaused = false;
+ this.pauseTime = 0;
+ this.totalPausedTime = 0;
+ this.bgMusic = null;
+ this.bgMusicPlaying = false;
+ this.bgMusicPaused = false;
+ this.calculatedPositions = [];
+ };
+ instanceProto.onDestroy = function () {
+ if (this.sdk) {
+ this.sdk.destroy();
+ }
+ if (this.bgMusic) {
+ this.bgMusic.pause();
+ this.bgMusic = null;
+ }
+ };
+ function Cnds() {
+ };
+ Cnds.prototype.OnLoad = function () {
+ return true;
+ };
+ Cnds.prototype.OnStart = function () {
+ return true;
+ };
+ Cnds.prototype.OnCorrect = function () {
+ return true;
+ };
+ Cnds.prototype.OnWrong = function () {
+ return true;
+ };
+ Cnds.prototype.OnPause = function () {
+ return true;
+ };
+ Cnds.prototype.OnResume = function () {
+ return true;
+ };
+ pluginProto.cnds = new Cnds();
+ function Acts() {
+ };
+ Acts.prototype.Load = function () {
+ var self = this;
+ var gameCode = this.properties[0] || 'G2510S1T30';
+ if (window['SenaSDK']) {
+ this.sdk = new window['SenaSDK'](gameCode);
+ this.sdk.load(function(success) {
+ if (success) {
+ console.log('SDK loaded successfully');
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnLoad, window['SenaTrigger']);
+ } else {
+ console.error('Failed to load SDK data');
+ }
+ }, gameCode);
+ } else {
+ console.error('SenaSDK not found');
+ }
+ };
+ Acts.prototype.Start = function () {
+ var self = this;
+ if (self.sdk) {
+ self.sdk.start();
+ console.log('Game started');
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnStart, window['SenaTrigger']);
+ }
+ };
+ Acts.prototype.Finish = function (answer) {
+ var self = this;
+ if (this.sdk) {
+ this.sdk.end(answer, function(isCorrect) {
+ if (isCorrect) {
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnCorrect, window['SenaTrigger']);
+ } else {
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnWrong, window['SenaTrigger']);
+ }
+ });
+ }
+ };
+ Acts.prototype.PlayVoice = function (type) {
+ var self = this;
+ if (this.sdk && this.sdk.playVoice) {
+ this.sdk.playVoice(type);
+ }
+ };
+ Acts.prototype.StopVoice = function () {
+ var self = this;
+ if (this.sdk && this.sdk.stopSound) {
+ this.sdk.stopSound();
+ }
+ };
+ Acts.prototype.PlayBGMusic = function () {
+ var self = this;
+ if (this.bgMusic) {
+ this.bgMusic.play();
+ this.bgMusicPlaying = true;
+ this.bgMusicPaused = false;
+ }
+ };
+ Acts.prototype.StopBGMusic = function () {
+ var self = this;
+ if (this.bgMusic) {
+ this.bgMusic.pause();
+ this.bgMusic.currentTime = 0;
+ this.bgMusicPlaying = false;
+ this.bgMusicPaused = false;
+ }
+ };
+ Acts.prototype.PauseBGMusic = function () {
+ var self = this;
+ if (this.bgMusic && this.bgMusicPlaying) {
+ this.bgMusic.pause();
+ this.bgMusicPaused = true;
+ }
+ };
+ Acts.prototype.ResumeBGMusic = function () {
+ var self = this;
+ if (this.bgMusic && this.bgMusicPaused) {
+ this.bgMusic.play();
+ this.bgMusicPaused = false;
+ }
+ };
+ Acts.prototype.PauseGame = function () {
+ var self = this;
+ if (!this.isPaused) {
+ this.isPaused = true;
+ this.pauseTime = Date.now();
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnPause, window['SenaTrigger']);
+ }
+ };
+ Acts.prototype.ResumeGame = function () {
+ var self = this;
+ if (this.isPaused) {
+ this.isPaused = false;
+ this.totalPausedTime += (Date.now() - this.pauseTime);
+ window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnResume, window['SenaTrigger']);
+ }
+ };
+ Acts.prototype.ResetGame = function () {
+ var self = this;
+ if (this.sdk && this.sdk.reset) {
+ this.sdk.reset();
+ this.isPaused = false;
+ this.pauseTime = 0;
+ this.totalPausedTime = 0;
+ }
+ };
+ Acts.prototype.CalcObjectPositions = function (
+ count,
+ objectWidth,
+ margin,
+ maxWidth,
+ rowBreak,
+ rowGap,
+ type
+) {
+ this.calculatedPositions = [];
+ if (count <= 0) return;
+ var rows = [];
+ if (rowBreak > 0) {
+ for (var i = 0; i < count; i += rowBreak) {
+ rows.push(Math.min(rowBreak, count - i));
+ }
+ } else {
+ if (count <= 5) {
+ rows.push(count);
+ } else {
+ var top = Math.ceil((count + 1) / 2);
+ var bottom = count - top;
+ rows.push(top);
+ rows.push(bottom);
+ }
+ }
+ var baseY = 0;
+ if (type === "word") {
+ baseY = rowGap * rows.length; // word luôn nằm dưới slot
+ }
+ var index = 0;
+ for (var r = 0; r < rows.length; r++) {
+ var itemsInRow = rows[r];
+ var rowWidth = itemsInRow * objectWidth + (itemsInRow - 1) * margin;
+ var startX = (maxWidth - rowWidth) / 2;
+ for (var i = 0; i < itemsInRow; i++) {
+ this.calculatedPositions.push({
+ x: startX + i * (objectWidth + margin) + objectWidth / 2,
+ y: baseY + r * rowGap
+ });
+ index++;
+ }
+ }
+};
+ pluginProto.acts = new Acts();
+ function Exps() {
+ };
+ Exps.prototype.getQuestionValue = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getQuestionValue() || "");
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getQuestionType = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getQuestionType() || "text");
+ } else {
+ ret.set_string("text");
+ }
+ };
+ Exps.prototype.getRequestValue = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getRequestValue() || "");
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getRequestType = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getRequestType() || "text");
+ } else {
+ ret.set_string("text");
+ }
+ };
+ Exps.prototype.getOptionsCount = function (ret) {
+ if (this.sdk) {
+ ret.set_int(this.sdk.getOptionsCount() || 0);
+ } else {
+ ret.set_int(0);
+ }
+ };
+ Exps.prototype.getOptionsType = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getOptionsType() || "text");
+ } else {
+ ret.set_string("text");
+ }
+ };
+ Exps.prototype.getOptionsValue = function (ret, index) {
+ if (this.sdk) {
+ var value = this.sdk.getOptionsValue(index);
+ if (value && typeof value === 'object') {
+ ret.set_string(JSON.stringify(value));
+ } else {
+ ret.set_string(value || "");
+ }
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getHintType = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.getHintType() || "");
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getHintCount = function (ret) {
+ if (this.sdk) {
+ ret.set_int(this.sdk.getHintCount() || 0);
+ } else {
+ ret.set_int(0);
+ }
+ };
+ Exps.prototype.getHintValue = function (ret, index) {
+ if (this.sdk) {
+ var value = this.sdk.getHintValue(index);
+ if (value === null) {
+ ret.set_string("");
+ } else if (typeof value === 'object') {
+ ret.set_string(JSON.stringify(value));
+ } else {
+ ret.set_string(value.toString());
+ }
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getTimeLimit = function (ret) {
+ if (this.sdk) {
+ ret.set_int(this.sdk.timeLimit || 0);
+ } else {
+ ret.set_int(0);
+ }
+ };
+ Exps.prototype.getShuffle = function (ret) {
+ if (this.sdk) {
+ ret.set_int(this.sdk.shuffle ? 1 : 0);
+ } else {
+ ret.set_int(1);
+ }
+ };
+ Exps.prototype.getGameCode = function (ret) {
+ if (this.sdk) {
+ ret.set_string(this.sdk.gameCode || "");
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.getGuide = function (ret) {
+ if (this.sdk && this.sdk.guide) {
+ ret.set_string(this.sdk.guide() || "");
+ } else {
+ ret.set_string("");
+ }
+ };
+ Exps.prototype.isVoicePlaying = function (ret) {
+ if (this.sdk && this.sdk.isSpeaking) {
+ ret.set_int(this.sdk.isSpeaking() ? 1 : 0);
+ } else {
+ ret.set_int(0);
+ }
+ };
+ Exps.prototype.isMusicPlaying = function (ret) {
+ ret.set_int(this.bgMusicPlaying ? 1 : 0);
+ };
+ Exps.prototype.isMusicPaused = function (ret) {
+ ret.set_int(this.bgMusicPaused ? 1 : 0);
+ };
+ Exps.prototype.isGamePaused = function (ret) {
+ ret.set_int(this.isPaused ? 1 : 0);
+ };
+ Exps.prototype.getElapsedTime = function (ret) {
+ if (this.sdk && this.sdk.startTime) {
+ var elapsed = (Date.now() - this.sdk.startTime - this.totalPausedTime) / 1000;
+ if (this.isPaused) {
+ elapsed -= (Date.now() - this.pauseTime) / 1000;
+ }
+ ret.set_float(Math.max(0, elapsed));
+ } else {
+ ret.set_float(0);
+ }
+ };
+ Exps.prototype.getPosXbyIndex = function (ret, index) {
+ if (this.calculatedPositions[index]) {
+ ret.set_float(this.calculatedPositions[index].x);
+ } else {
+ ret.set_float(0);
+ }
+};
+Exps.prototype.getPosYbyIndex = function (ret, index) {
+ if (this.calculatedPositions[index]) {
+ ret.set_float(this.calculatedPositions[index].y);
+ } else {
+ ret.set_float(0);
+ }
+};
+ pluginProto.exps = new Exps();
+}());
+;
+;
cr.plugins_.Sprite = function(runtime)
{
this.runtime = runtime;
@@ -21345,744 +21712,6 @@ cr.plugins_.SpriteFontPlus = function(runtime)
}());
;
;
-cr.plugins_.TDVplugin = function (runtime) {
- this.runtime = runtime;
-};
-(function () {
- var pluginProto = cr.plugins_.TDVplugin.prototype;
- pluginProto.Type = function (plugin) {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function () {
- };
- pluginProto.Instance = function (type) {
- this.type = type;
- this.runtime = type.runtime;
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onCreate = function () {
- window['TDVTriger'] = this;
- };
- instanceProto.onDestroy = function () {
- };
- function Cnds() {
- };
- Cnds.prototype.OnStart = function (tag) {
- return true;
- };
- Cnds.prototype.OnCorrect = function (tag) {
- return true;
- };
- Cnds.prototype.OnWrong = function (tag) {
- return true;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {
- };
- Acts.prototype.START = function () {
- var self = this;
- console.log('## START');
- window['TDVTriger'].runtime.trigger(cr.plugins_.TDVplugin.prototype.cnds.OnStart, window['TDVTriger']);
- };
- Acts.prototype.END = function () {
- var self = this;
- console.log('## END');
- if (window['tdv_sdk'])
- if (window['tdv_sdk']['end'])
- window['tdv_sdk']['end']();
- };
- Acts.prototype.FINISH = function (answer) {
- var self = this;
- console.log('## FINISH');
- if (window['tdv_sdk']) {
- if (window['tdv_sdk'].questions && window['tdv_sdk'].questions.answer) {
- if (window['tdv_sdk'].questions.answer.toLowerCase() === answer.toLowerCase()) {
- window['TDVTriger'].runtime.trigger(cr.plugins_.TDVplugin.prototype.cnds.OnCorrect, window['TDVTriger']);
- } else {
- window['TDVTriger'].runtime.trigger(cr.plugins_.TDVplugin.prototype.cnds.OnWrong, window['TDVTriger']);
- }
- } else {
- console.error('No answer found in tdv_sdk');
- }
- }
- }
- pluginProto.acts = new Acts();
- function Exps() {
- };
- pluginProto.exps = {};
- var exps = pluginProto.exps;
- Exps.prototype.getData = function (ret,key) {
- switch (key) {
- case 'question':
- ret.set_string(window['tdv_sdk'].questions.question || '');
- break;
- case 'request':
- ret.set_string(window['tdv_sdk'].questions.request || '');
- break;
- case 'answer':
- ret.set_string(window['tdv_sdk'].questions.answer || '');
- break;
- case 'voice':
- ret.set_string(window['tdv_sdk'].questions.voice || '');
- break;
- case 'answerA':
- console.log('answerA', window['tdv_sdk'].questions.options[0]);
- ret.set_string(window['tdv_sdk'].questions.options[0] || '');
- break;
- case 'answerB':
- console.log('answerB', window['tdv_sdk'].questions.options[1]);
- ret.set_string(window['tdv_sdk'].questions.options[1] || '');
- break;
- case 'answerC':
- console.log('answerC', window['tdv_sdk'].questions.options[2]);
- ret.set_string(window['tdv_sdk'].questions.options[2] || '');
- break;
- case 'answerD':
- console.log('answerD', window['tdv_sdk'].questions.options[3]);
- ret.set_string(window['tdv_sdk'].questions.options[3] || '');
- break;
- }
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.Text = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Text.prototype;
- pluginProto.onCreate = function ()
- {
- pluginProto.acts.SetWidth = function (w)
- {
- if (this.width !== w)
- {
- this.width = w;
- this.text_changed = true; // also recalculate text wrapping
- this.set_bbox_changed();
- }
- };
- };
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- };
- typeProto.onLostWebGLContext = function ()
- {
- if (this.is_family)
- return;
- var i, len, inst;
- for (i = 0, len = this.instances.length; i < len; i++)
- {
- inst = this.instances[i];
- inst.mycanvas = null;
- inst.myctx = null;
- inst.mytex = null;
- }
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- if (this.recycled)
- cr.clearArray(this.lines);
- else
- this.lines = []; // for word wrapping
- this.text_changed = true;
- };
- var instanceProto = pluginProto.Instance.prototype;
- var requestedWebFonts = {}; // already requested web fonts have an entry here
- instanceProto.onCreate = function()
- {
- this.text = this.properties[0];
- this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible
- this.font = this.properties[2];
- this.color = this.properties[3];
- this.halign = this.properties[4]; // 0=left, 1=center, 2=right
- this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom
- this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character
- this.lastwidth = this.width;
- this.lastwrapwidth = this.width;
- this.lastheight = this.height;
- this.line_height_offset = this.properties[8];
- this.facename = "";
- this.fontstyle = "";
- this.ptSize = 0;
- this.textWidth = 0;
- this.textHeight = 0;
- this.parseFont();
- this.mycanvas = null;
- this.myctx = null;
- this.mytex = null;
- this.need_text_redraw = false;
- this.last_render_tick = this.runtime.tickcount;
- if (this.recycled)
- this.rcTex.set(0, 0, 1, 1);
- else
- this.rcTex = new cr.rect(0, 0, 1, 1);
- if (this.runtime.glwrap)
- this.runtime.tickMe(this);
-;
- };
- instanceProto.parseFont = function ()
- {
- var arr = this.font.split(" ");
- var i;
- for (i = 0; i < arr.length; i++)
- {
- if (arr[i].substr(arr[i].length - 2, 2) === "pt")
- {
- this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2));
- this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
- if (i > 0)
- this.fontstyle = arr[i - 1];
- this.facename = arr[i + 1];
- for (i = i + 2; i < arr.length; i++)
- this.facename += " " + arr[i];
- break;
- }
- }
- };
- instanceProto.saveToJSON = function ()
- {
- return {
- "t": this.text,
- "f": this.font,
- "c": this.color,
- "ha": this.halign,
- "va": this.valign,
- "wr": this.wrapbyword,
- "lho": this.line_height_offset,
- "fn": this.facename,
- "fs": this.fontstyle,
- "ps": this.ptSize,
- "pxh": this.pxHeight,
- "tw": this.textWidth,
- "th": this.textHeight,
- "lrt": this.last_render_tick
- };
- };
- instanceProto.loadFromJSON = function (o)
- {
- this.text = o["t"];
- this.font = o["f"];
- this.color = o["c"];
- this.halign = o["ha"];
- this.valign = o["va"];
- this.wrapbyword = o["wr"];
- this.line_height_offset = o["lho"];
- this.facename = o["fn"];
- this.fontstyle = o["fs"];
- this.ptSize = o["ps"];
- this.pxHeight = o["pxh"];
- this.textWidth = o["tw"];
- this.textHeight = o["th"];
- this.last_render_tick = o["lrt"];
- this.text_changed = true;
- this.lastwidth = this.width;
- this.lastwrapwidth = this.width;
- this.lastheight = this.height;
- };
- instanceProto.tick = function ()
- {
- if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300))
- {
- var layer = this.layer;
- this.update_bbox();
- var bbox = this.bbox;
- if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom)
- {
- this.runtime.glwrap.deleteTexture(this.mytex);
- this.mytex = null;
- this.myctx = null;
- this.mycanvas = null;
- }
- }
- };
- instanceProto.onDestroy = function ()
- {
- this.myctx = null;
- this.mycanvas = null;
- if (this.runtime.glwrap && this.mytex)
- this.runtime.glwrap.deleteTexture(this.mytex);
- this.mytex = null;
- };
- instanceProto.updateFont = function ()
- {
- this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename;
- this.text_changed = true;
- this.runtime.redraw = true;
- };
- instanceProto.draw = function(ctx, glmode)
- {
- ctx.font = this.font;
- ctx.textBaseline = "top";
- ctx.fillStyle = this.color;
- ctx.globalAlpha = glmode ? 1 : this.opacity;
- var myscale = 1;
- if (glmode)
- {
- myscale = Math.abs(this.layer.getScale());
- ctx.save();
- ctx.scale(myscale, myscale);
- }
- if (this.text_changed || this.width !== this.lastwrapwidth)
- {
- this.type.plugin.WordWrap(this.text, this.lines, ctx, this.width, this.wrapbyword);
- this.text_changed = false;
- this.lastwrapwidth = this.width;
- }
- this.update_bbox();
- var penX = glmode ? 0 : this.bquad.tlx;
- var penY = glmode ? 0 : this.bquad.tly;
- if (this.runtime.pixel_rounding)
- {
- penX = (penX + 0.5) | 0;
- penY = (penY + 0.5) | 0;
- }
- if (this.angle !== 0 && !glmode)
- {
- ctx.save();
- ctx.translate(penX, penY);
- ctx.rotate(this.angle);
- penX = 0;
- penY = 0;
- }
- var endY = penY + this.height;
- var line_height = this.pxHeight;
- line_height += this.line_height_offset;
- var drawX;
- var i;
- if (this.valign === 1) // center
- penY += Math.max(this.height / 2 - (this.lines.length * line_height) / 2, 0);
- else if (this.valign === 2) // bottom
- penY += Math.max(this.height - (this.lines.length * line_height) - 2, 0);
- for (i = 0; i < this.lines.length; i++)
- {
- drawX = penX;
- if (this.halign === 1) // center
- drawX = penX + (this.width - this.lines[i].width) / 2;
- else if (this.halign === 2) // right
- drawX = penX + (this.width - this.lines[i].width);
- ctx.fillText(this.lines[i].text, drawX, penY);
- penY += line_height;
- if (penY >= endY - line_height)
- break;
- }
- if (this.angle !== 0 || glmode)
- ctx.restore();
- this.last_render_tick = this.runtime.tickcount;
- };
- instanceProto.drawGL = function(glw)
- {
- if (this.width < 1 || this.height < 1)
- return;
- var need_redraw = this.text_changed || this.need_text_redraw;
- this.need_text_redraw = false;
- var layer_scale = this.layer.getScale();
- var layer_angle = this.layer.getAngle();
- var rcTex = this.rcTex;
- var floatscaledwidth = layer_scale * this.width;
- var floatscaledheight = layer_scale * this.height;
- var scaledwidth = Math.ceil(floatscaledwidth);
- var scaledheight = Math.ceil(floatscaledheight);
- var absscaledwidth = Math.abs(scaledwidth);
- var absscaledheight = Math.abs(scaledheight);
- var halfw = this.runtime.draw_width / 2;
- var halfh = this.runtime.draw_height / 2;
- if (!this.myctx)
- {
- this.mycanvas = document.createElement("canvas");
- this.mycanvas.width = absscaledwidth;
- this.mycanvas.height = absscaledheight;
- this.lastwidth = absscaledwidth;
- this.lastheight = absscaledheight;
- need_redraw = true;
- this.myctx = this.mycanvas.getContext("2d");
- }
- if (absscaledwidth !== this.lastwidth || absscaledheight !== this.lastheight)
- {
- this.mycanvas.width = absscaledwidth;
- this.mycanvas.height = absscaledheight;
- if (this.mytex)
- {
- glw.deleteTexture(this.mytex);
- this.mytex = null;
- }
- need_redraw = true;
- }
- if (need_redraw)
- {
- this.myctx.clearRect(0, 0, absscaledwidth, absscaledheight);
- this.draw(this.myctx, true);
- if (!this.mytex)
- this.mytex = glw.createEmptyTexture(absscaledwidth, absscaledheight, this.runtime.linearSampling, this.runtime.isMobile);
- glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile);
- }
- this.lastwidth = absscaledwidth;
- this.lastheight = absscaledheight;
- glw.setTexture(this.mytex);
- glw.setOpacity(this.opacity);
- glw.resetModelView();
- glw.translate(-halfw, -halfh);
- glw.updateModelView();
- var q = this.bquad;
- var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true);
- var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true);
- var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true);
- var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true);
- var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true);
- var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true);
- var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true);
- var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true);
- if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0))
- {
- var ox = ((tlx + 0.5) | 0) - tlx;
- var oy = ((tly + 0.5) | 0) - tly
- tlx += ox;
- tly += oy;
- trx += ox;
- try_ += oy;
- brx += ox;
- bry += oy;
- blx += ox;
- bly += oy;
- }
- if (this.angle === 0 && layer_angle === 0)
- {
- trx = tlx + scaledwidth;
- try_ = tly;
- brx = trx;
- bry = tly + scaledheight;
- blx = tlx;
- bly = bry;
- rcTex.right = 1;
- rcTex.bottom = 1;
- }
- else
- {
- rcTex.right = floatscaledwidth / scaledwidth;
- rcTex.bottom = floatscaledheight / scaledheight;
- }
- glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex);
- glw.resetModelView();
- glw.scale(layer_scale, layer_scale);
- glw.rotateZ(-this.layer.getAngle());
- glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2);
- glw.updateModelView();
- this.last_render_tick = this.runtime.tickcount;
- };
- var wordsCache = [];
- pluginProto.TokeniseWords = function (text)
- {
- cr.clearArray(wordsCache);
- var cur_word = "";
- var ch;
- var i = 0;
- while (i < text.length)
- {
- ch = text.charAt(i);
- if (ch === "\n")
- {
- if (cur_word.length)
- {
- wordsCache.push(cur_word);
- cur_word = "";
- }
- wordsCache.push("\n");
- ++i;
- }
- else if (ch === " " || ch === "\t" || ch === "-")
- {
- do {
- cur_word += text.charAt(i);
- i++;
- }
- while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
- wordsCache.push(cur_word);
- cur_word = "";
- }
- else if (i < text.length)
- {
- cur_word += ch;
- i++;
- }
- }
- if (cur_word.length)
- wordsCache.push(cur_word);
- };
- var linesCache = [];
- function allocLine()
- {
- if (linesCache.length)
- return linesCache.pop();
- else
- return {};
- };
- function freeLine(l)
- {
- linesCache.push(l);
- };
- function freeAllLines(arr)
- {
- var i, len;
- for (i = 0, len = arr.length; i < len; i++)
- {
- freeLine(arr[i]);
- }
- cr.clearArray(arr);
- };
- pluginProto.WordWrap = function (text, lines, ctx, width, wrapbyword)
- {
- if (!text || !text.length)
- {
- freeAllLines(lines);
- return;
- }
- if (width <= 2.0)
- {
- freeAllLines(lines);
- return;
- }
- if (text.length <= 100 && text.indexOf("\n") === -1)
- {
- var all_width = ctx.measureText(text).width;
- if (all_width <= width)
- {
- freeAllLines(lines);
- lines.push(allocLine());
- lines[0].text = text;
- lines[0].width = all_width;
- return;
- }
- }
- this.WrapText(text, lines, ctx, width, wrapbyword);
- };
- function trimSingleSpaceRight(str)
- {
- if (!str.length || str.charAt(str.length - 1) !== " ")
- return str;
- return str.substring(0, str.length - 1);
- };
- pluginProto.WrapText = function (text, lines, ctx, width, wrapbyword)
- {
- var wordArray;
- if (wrapbyword)
- {
- this.TokeniseWords(text); // writes to wordsCache
- wordArray = wordsCache;
- }
- else
- wordArray = text;
- var cur_line = "";
- var prev_line;
- var line_width;
- var i;
- var lineIndex = 0;
- var line;
- for (i = 0; i < wordArray.length; i++)
- {
- if (wordArray[i] === "\n")
- {
- if (lineIndex >= lines.length)
- lines.push(allocLine());
- cur_line = trimSingleSpaceRight(cur_line); // for correct center/right alignment
- line = lines[lineIndex];
- line.text = cur_line;
- line.width = ctx.measureText(cur_line).width;
- lineIndex++;
- cur_line = "";
- continue;
- }
- prev_line = cur_line;
- cur_line += wordArray[i];
- line_width = ctx.measureText(cur_line).width;
- if (line_width >= width)
- {
- if (lineIndex >= lines.length)
- lines.push(allocLine());
- prev_line = trimSingleSpaceRight(prev_line);
- line = lines[lineIndex];
- line.text = prev_line;
- line.width = ctx.measureText(prev_line).width;
- lineIndex++;
- cur_line = wordArray[i];
- if (!wrapbyword && cur_line === " ")
- cur_line = "";
- }
- }
- if (cur_line.length)
- {
- if (lineIndex >= lines.length)
- lines.push(allocLine());
- cur_line = trimSingleSpaceRight(cur_line);
- line = lines[lineIndex];
- line.text = cur_line;
- line.width = ctx.measureText(cur_line).width;
- lineIndex++;
- }
- for (i = lineIndex; i < lines.length; i++)
- freeLine(lines[i]);
- lines.length = lineIndex;
- };
- function Cnds() {};
- Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
- {
- if (case_sensitive)
- return this.text == text_to_compare;
- else
- return cr.equals_nocase(this.text, text_to_compare);
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.SetText = function(param)
- {
- if (cr.is_number(param) && param < 1e9)
- param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
- var text_to_set = param.toString();
- if (this.text !== text_to_set)
- {
- this.text = text_to_set;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.AppendText = function(param)
- {
- if (cr.is_number(param))
- param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
- var text_to_append = param.toString();
- if (text_to_append) // not empty
- {
- this.text += text_to_append;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.SetFontFace = function (face_, style_)
- {
- var newstyle = "";
- switch (style_) {
- case 1: newstyle = "bold"; break;
- case 2: newstyle = "italic"; break;
- case 3: newstyle = "bold italic"; break;
- }
- if (face_ === this.facename && newstyle === this.fontstyle)
- return; // no change
- this.facename = face_;
- this.fontstyle = newstyle;
- this.updateFont();
- };
- Acts.prototype.SetFontSize = function (size_)
- {
- if (this.ptSize === size_)
- return;
- this.ptSize = size_;
- this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
- this.updateFont();
- };
- Acts.prototype.SetFontColor = function (rgb)
- {
- var newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")";
- if (newcolor === this.color)
- return;
- this.color = newcolor;
- this.need_text_redraw = true;
- this.runtime.redraw = true;
- };
- Acts.prototype.SetWebFont = function (familyname_, cssurl_)
- {
- if (this.runtime.isDomFree)
- {
- cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored");
- return; // DC todo
- }
- var self = this;
- var refreshFunc = (function () {
- self.runtime.redraw = true;
- self.text_changed = true;
- });
- if (requestedWebFonts.hasOwnProperty(cssurl_))
- {
- var newfacename = "'" + familyname_ + "'";
- if (this.facename === newfacename)
- return; // no change
- this.facename = newfacename;
- this.updateFont();
- for (var i = 1; i < 10; i++)
- {
- setTimeout(refreshFunc, i * 100);
- setTimeout(refreshFunc, i * 1000);
- }
- return;
- }
- var wf = document.createElement("link");
- wf.href = cssurl_;
- wf.rel = "stylesheet";
- wf.type = "text/css";
- wf.onload = refreshFunc;
- document.getElementsByTagName('head')[0].appendChild(wf);
- requestedWebFonts[cssurl_] = true;
- this.facename = "'" + familyname_ + "'";
- this.updateFont();
- for (var i = 1; i < 10; i++)
- {
- setTimeout(refreshFunc, i * 100);
- setTimeout(refreshFunc, i * 1000);
- }
-;
- };
- Acts.prototype.SetEffect = function (effect)
- {
- this.blend_mode = effect;
- this.compositeOp = cr.effectToCompositeOp(effect);
- cr.setGLBlend(this, effect, this.runtime.gl);
- this.runtime.redraw = true;
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.Text = function(ret)
- {
- ret.set_string(this.text);
- };
- Exps.prototype.FaceName = function (ret)
- {
- ret.set_string(this.facename);
- };
- Exps.prototype.FaceSize = function (ret)
- {
- ret.set_int(this.ptSize);
- };
- Exps.prototype.TextWidth = function (ret)
- {
- var w = 0;
- var i, len, x;
- for (i = 0, len = this.lines.length; i < len; i++)
- {
- x = this.lines[i].width;
- if (w < x)
- w = x;
- }
- ret.set_int(w);
- };
- Exps.prototype.TextHeight = function (ret)
- {
- ret.set_int(this.lines.length * (this.pxHeight + this.line_height_offset) - this.line_height_offset);
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
cr.plugins_.Touch = function(runtime)
{
this.runtime = runtime;
@@ -24699,1441 +24328,103 @@ cr.behaviors.Sin = function(runtime)
};
behaviorProto.exps = new Exps();
}());
-;
-;
-function trim (str) {
- return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
-}
-cr.behaviors.lunarray_Tween = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.lunarray_Tween.prototype;
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- this.i = 0; // progress
- };
- var behinstProto = behaviorProto.Instance.prototype;
- behinstProto.groupUpdateProgress = function(v)
- {
- if (v > 1) v = 1;
- if (cr.lunarray_tweenProgress[this.group] = -1) cr.lunarray_tweenProgress[this.group] = v;
- if (cr.lunarray_tweenProgress[this.group] >= v) cr.lunarray_tweenProgress[this.group] = v;
- }
- behinstProto.groupSync = function()
- {
- if (this.group != "") {
- if (typeof cr.lunarray_tweenGroup === "undefined") {
- cr.lunarray_tweenGroup = {};
- cr.lunarray_tweenProgress = {};
- }
- if (typeof cr.lunarray_tweenGroup[this.group] === "undefined") {
- cr.lunarray_tweenGroup[this.group] = [];
- cr.lunarray_tweenProgress[this.group] = -1;
- }
- if (cr.lunarray_tweenGroup[this.group].indexOf(this) == -1) {
- cr.lunarray_tweenGroup[this.group].push(this);
- }
- }
- }
- behinstProto.saveState = function()
- {
- this.tweenSaveWidth = this.inst.width;
- this.tweenSaveHeight = this.inst.height;
- this.tweenSaveAngle = this.inst.angle;
- this.tweenSaveOpacity = this.inst.opacity;
- this.tweenSaveX = this.inst.x;
- this.tweenSaveY = this.inst.y;
- this.tweenSaveValue = this.value;
- }
- behinstProto.onCreate = function()
- {
- this.active = (this.properties[0] === 1);
- this.tweened = this.properties[1]; // 0=Position|1=Size|2=Width|3=Height|4=Angle|5=Opacity|6=Value only|7=Pixel Size
- this.easing = this.properties[2];
- this.initial = this.properties[3];
- this.target = this.properties[4];
- this.duration = this.properties[5];
- this.wait = this.properties[6];
- this.playmode = this.properties[7]; //0=Play Once|1=Repeat|2=Ping Pong|3=Play once and destroy|4=Loop|5=Ping Pong Stop|6=Play and stop
- this.value = this.properties[8];
- this.coord_mode = this.properties[9]; //0=Absolute|1=Relative
- this.forceInit = (this.properties[10] === 1);
- this.group = this.properties[11];
- this.targetObject = null;
- this.pingpongCounter = 0;
- if (this.playmode == 5) this.pingpongCounter = 1;
- this.groupSync();
- this.isPaused = false;
- this.initialX = this.inst.x;
- this.initialY = this.inst.y;
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- this.saveState();
- this.tweenInitialX = 0;
- this.tweenInitialY = 0;
- this.tweenTargetX = 0;
- this.tweenTargetY = 0;
- this.tweenTargetAngle = 0;
- this.ratio = this.inst.height / this.inst.width;
- this.reverse = false;
- this.rewindMode = false;
- this.doTweenX = true;
- this.doTweenY = true;
- this.loop = false;
- this.initiating = 0;
- this.cooldown = 0;
- this.lastPlayMode = this.playmode;
- this.lastKnownValue = this.tweenInitialX;
- this.lastKnownX = this.tweenInitialX;
- this.lastKnownY = this.tweenInitialY;
- if (this.forceInit) this.init();
- if (this.initial == "") this.initial = "current";
- this.onStarted = false;
- this.onStartedDone = false;
- this.onWaitEnd = false;
- this.onWaitEndDone = false;
- this.onEnd = false;
- this.onEndDone = false;
- this.onCooldown = false;
- this.onCooldownDone = false;
- if (this.active) {
- this.init();
- }
- };
- behinstProto.init = function ()
- {
- this.onStarted = false;
- if (this.initial === "") this.initial = "current";
- if (this.target === "") this.target = "current";
- var isCurrent = (this.initial === "current");
- var targetIsCurrent = (this.target === "current");
- var isTargettingObject = (this.target === "OBJ");
- if (this.target === "OBJ") {
- if (this.targetObject != null) {
- if (this.tweened == 0) {
- if (this.coord_mode == 1) //relative mode
- this.target = (this.targetObject.x-this.inst.x) + "," + (this.targetObject.y-this.inst.y);
- else //absolute mode
- this.target = (this.targetObject.x) + "," + (this.targetObject.y);
- } else if ((this.tweened == 1) || (this.tweened == 2) || (this.tweened == 3) || (this.tweened == 7)) {
- if (this.coord_mode == 1) { //relative mode
- this.target = ((this.tweened==2)?1:(this.targetObject.width)) + "," + ((this.tweened==3)?1:(this.targetObject.height));
- } else {
- this.target = ((this.tweened==2)?1:(this.targetObject.width/this.tweenSaveWidth)) + "," + ((this.tweened==3)?1:(this.targetObject.height/this.tweenSaveHeight));
- }
- } else if (this.tweened == 4) {
- if (this.coord_mode == 1) //relative mode
- this.target = cr.to_degrees(this.targetObject.angle-this.inst.angle) + "";
- else //absolute mode
- this.target = cr.to_degrees(this.targetObject.angle) + "";
- } else if (this.tweened == 5) {
- if (this.coord_mode == 1) //relative mode
- this.target = ((this.targetObject.opacity-this.inst.opacity)*100) + "";
- else //absolute mode
- this.target = (this.targetObject.opacity*100) + "";
- }
- }
- }
- if (this.tweened == 0) {
- if (targetIsCurrent) this.target = this.inst.x + "," + this.inst.y;
- if (!isCurrent) {
- if (!this.reverse) {
- if (this.playmode != 1) {
- this.inst.x = parseFloat(this.initial.split(",")[0]);
- this.inst.y = parseFloat(this.initial.split(",")[1]);
- }
- }
- } else {
- if (this.coord_mode == 1) {
- this.initial = this.inst.x + "," + this.inst.y;
- } else {
- this.initial = this.tweenSaveX + "," + this.tweenSaveY;
- }
- }
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.inst.x = this.tweenSaveX;
- this.inst.y = this.tweenSaveY;
- }
- this.initialX = this.inst.x;
- this.initialY = this.inst.y;
- if (!this.reverse) {
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- } else {
- this.targetX = -parseFloat(this.target.split(",")[0]);
- this.targetY = -parseFloat(this.target.split(",")[1]);
- }
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- this.tweenTargetX = this.tweenInitialX + this.targetX;
- this.tweenTargetY = this.tweenInitialY + this.targetY;
- } else {
- if (!this.reverse) {
- this.inst.x = this.tweenSaveX;
- this.inst.y = this.tweenSaveY;
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- } else {
- this.inst.x = parseFloat(this.target.split(",")[0]);
- this.inst.y = parseFloat(this.target.split(",")[1]);
- this.targetX = this.tweenSaveX;
- this.targetY = this.tweenSaveY;
- }
- this.initialX = this.inst.x;
- this.initialY = this.inst.y;
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- this.tweenTargetX = this.targetX;
- this.tweenTargetY = this.targetY;
- if (this.playmode == -6) {
- this.tweenTargetX = this.tweenSaveX;
- this.tweenTargetY = this.tweenSaveY;
- }
- }
- } else if ((this.tweened == 1) || (this.tweened == 2) || (this.tweened == 3)) {
- if (targetIsCurrent) this.target = "1,1";
- if (this.initial == "current") this.initial = "1,1";
- this.initial = "" + this.initial;
- this.target = "" + this.target;
- if (this.tweened == 2) {
- if (this.initial.indexOf(',') == -1) this.initial = parseFloat(this.initial) + ",1";
- if (this.target.indexOf(',') == -1) this.target = parseFloat(this.target) + ",1";
- } else if (this.tweened == 3) {
- if (this.initial.indexOf(',') == -1) this.initial = "1," + parseFloat(this.initial);
- if (this.target.indexOf(',') == -1) this.target = "1," + parseFloat(this.target);
- } else {
- if (this.initial.indexOf(',') == -1) this.initial = parseFloat(this.initial) + "," + parseFloat(this.initial);
- if (this.target.indexOf(',') == -1) this.target = parseFloat(this.target) + "," + parseFloat(this.target);
- }
- var ix = parseFloat(this.initial.split(",")[0]);
- var iy = parseFloat(this.initial.split(",")[1]);
- this.doTweenX = true;
- var tx = parseFloat(this.target.split(",")[0]);
- if ((tx == 0) || (isNaN(tx))) this.doTweenX = false;
- if (this.tweened == 3) this.doTweenX = false;
- this.doTweenY = true;
- var ty = parseFloat(this.target.split(",")[1]);
- if ((ty == 0) || (isNaN(ty))) this.doTweenY = false;
- if (this.tweened == 2) this.doTweenY = false;
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.inst.width = this.tweenSaveWidth;
- this.inst.height = this.tweenSaveHeight;
- }
- if (!isCurrent) {
- if (!this.reverse) {
- this.inst.width = this.inst.width * ix;
- this.inst.height = this.inst.height * iy;
- } else {
- this.inst.width = this.inst.width * tx;
- this.inst.height = this.inst.height * ty;
- }
- }
- this.initialX = this.inst.width;
- this.initialY = this.inst.height;
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- if (!this.reverse) {
- this.targetX = this.initialX * tx;
- this.targetY = this.initialY * ty;
- } else {
- this.targetX = this.initialX * ix/tx;
- this.targetY = this.initialY * iy/ty;
- }
- this.tweenTargetX = this.targetX;
- this.tweenTargetY = this.targetY;
- } else {
- if (!isCurrent) {
- if (!this.reverse) {
- this.inst.width = this.tweenSaveWidth * ix;
- this.inst.height = this.tweenSaveHeight * iy;
- } else {
- this.inst.width = this.tweenSaveWidth * tx;
- this.inst.height = this.tweenSaveHeight * ty;
- }
- }
- this.initialX = this.inst.width;
- this.initialY = this.inst.height;
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- if (!this.reverse) {
- this.targetX = this.tweenSaveWidth * tx;
- this.targetY = this.tweenSaveHeight * ty;
- } else {
- this.targetX = this.tweenSaveWidth * ix;
- this.targetY = this.tweenSaveHeight * iy;
- }
- this.tweenTargetX = this.targetX;
- this.tweenTargetY = this.targetY;
- }
- if (this.playmode == -6) {
- this.tweenTargetX = this.tweenSaveWidth * ix;
- this.tweenTargetY = this.tweenSaveHeight * iy;
- }
- } else if (this.tweened == 4) {
- if (targetIsCurrent) this.target = cr.to_degrees(this.inst.angle);
- if (this.initial != "current") {
- if (!this.reverse) {
- if (this.playmode != 1) { //if repeat, don't initialize
- this.inst.angle = cr.to_radians(parseFloat(this.initial.split(",")[0]));
- }
- }
- }
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.inst.angle = this.tweenSaveAngle;
- }
- this.initialX = this.inst.angle;
- if (this.reverse) {
- this.targetX = this.inst.angle - cr.to_radians(parseFloat(this.target.split(",")[0]));
- } else {
- this.targetX = this.inst.angle + cr.to_radians(parseFloat(this.target.split(",")[0]));
- }
- this.tweenInitialX = this.initialX;
- this.tweenTargetX = cr.to_degrees(this.targetX);
- } else {
- if (this.reverse) {
- this.inst.angle = cr.to_radians(parseFloat(this.target.split(",")[0]));;
- this.initialX = this.inst.angle;
- this.targetX = this.tweenSaveAngle;
- this.tweenInitialX = this.initialX;
- this.tweenTargetX = cr.to_degrees(this.targetX);
- } else {
- this.inst.angle = this.tweenSaveAngle;
- this.initialX = this.inst.angle;
- this.targetX = cr.to_radians(parseFloat(this.target.split(",")[0]));
- this.tweenInitialX = this.initialX;
- this.tweenTargetX = cr.to_degrees(this.targetX);
- }
- }
- if (this.playmode == -6) {
- this.tweenTargetX = cr.to_degrees(this.tweenSaveAngle);
- }
- this.tweenTargetAngle = cr.to_radians(this.tweenTargetX);
- } else if (this.tweened == 5) {
- if (this.initial == "current") this.initial = this.inst.opacity;
- if (targetIsCurrent) this.target = ""+this.inst.opacity;
- if (!isCurrent) {
- if (!this.reverse) {
- if (this.playmode != 1) { //if repeat, don't initialize
- this.inst.opacity = parseFloat(this.initial.split(",")[0]) / 100;
- }
- }
- }
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.inst.opacity = this.tweenSaveOpacity;
- }
- this.initialX = this.inst.opacity;
- this.tweenInitialX = this.initialX;
- if (!this.reverse) {
- this.targetX = parseFloat(this.target.split(",")[0]) / 100;
- } else {
- this.targetX = -parseFloat(this.target.split(",")[0]) / 100;
- }
- this.tweenTargetX = this.tweenInitialX + this.targetX;
- } else {
- this.initialX = this.inst.opacity;
- if (!this.reverse) {
- this.tweenInitialX = this.initialX;
- this.targetX = parseFloat(this.target.split(",")[0]) / 100;
- } else {
- this.tweenInitialX = parseFloat(this.target.split(",")[0]) / 100;
- this.targetX = parseFloat(this.initial.split(",")[0]) / 100;
- }
- this.tweenTargetX = this.targetX;
- }
- if (this.playmode == -6) {
- this.tweenTargetX = this.tweenSaveOpacity;
- }
- } else if (this.tweened == 6) {
- if (isNaN(this.value)) this.value = 0;
- if (this.initial == "current") this.initial = ""+this.value;
- if (targetIsCurrent) this.target = ""+this.value;
- if (!isCurrent) {
- if (!this.reverse) {
- if (this.playmode != 1) { //if repeat, don't initialize
- this.value = parseFloat(this.initial.split(",")[0]);
- }
- }
- }
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.value = this.tweenSaveValue;
- }
- if (!isCurrent) {
- if (!this.reverse) {
- this.value = parseFloat(this.initial.split(",")[0]);
- } else {
- this.value = parseFloat(this.target.split(",")[0]);
- }
- }
- this.initialX = this.value;
- if (!this.reverse) {
- this.targetX = this.initialX + parseFloat(this.target.split(",")[0]);
- } else {
- this.targetX = this.initialX - parseFloat(this.target.split(",")[0]);
- }
- this.tweenInitialX = this.initialX;
- this.tweenTargetX = this.targetX;
- } else {
- if (!isCurrent) {
- if (!this.reverse) {
- this.value = parseFloat(this.initial.split(",")[0]);
- } else {
- this.value = parseFloat(this.target.split(",")[0]);
- }
- }
- this.initialX = this.value;
- if (!this.reverse) {
- this.targetX = parseFloat(this.target.split(",")[0]);
- } else {
- this.targetX = parseFloat(this.initial.split(",")[0]);
- }
- this.tweenInitialX = this.initialX;
- this.tweenTargetX = this.targetX;
- }
- if (this.playmode == -6) {
- this.tweenTargetX = this.tweenSaveValue;
- }
- } else if (this.tweened == 7) {
- if (targetIsCurrent) this.target = this.inst.width + "," + this.inst.height;
- if (this.initial != "current") {
- if (!this.reverse) {
- if (this.playmode != 1) { //if repeat, don't initialize
- this.inst.width = parseFloat(this.initial.split(",")[0]);
- this.inst.height = parseFloat(this.initial.split(",")[1]);
- }
- }
- }
- this.doTweenX = true;
- var tx = parseFloat(this.target.split(",")[0]);
- if ((tx < 0) || (isNaN(tx))) this.doTweenX = false;
- this.doTweenY = true;
- var ty = parseFloat(this.target.split(",")[1]);
- if ((ty < 0) || (isNaN(ty))) this.doTweenY = false;
- if (this.coord_mode == 1) {
- if (this.loop) {
- this.inst.width = this.tweenSaveWidth;
- this.inst.height = this.tweenSaveHeight;
- }
- this.initialX = this.inst.width;
- this.initialY = this.inst.height;
- if (!this.reverse) {
- this.targetX = this.initialX + parseFloat(this.target.split(",")[0]);
- this.targetY = this.initialY + parseFloat(this.target.split(",")[1]);
- } else {
- this.targetX = this.initialX - parseFloat(this.target.split(",")[0]);
- this.targetY = this.initialY - parseFloat(this.target.split(",")[1]);
- }
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- this.tweenTargetX = this.targetX;
- this.tweenTargetY = this.targetY;
- } else {
- if (!isCurrent) {
- if (!this.reverse) {
- this.inst.width = this.tweenSaveWidth;
- this.inst.height = this.tweenSaveHeight;
- } else {
- this.inst.width = parseFloat(this.target.split(",")[0]);
- this.inst.height = parseFloat(this.target.split(",")[1]);
- }
- }
- this.initialX = this.inst.width;
- this.initialY = this.inst.height;
- if (!this.reverse) {
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- } else {
- this.targetX = this.tweenSaveWidth;
- this.targetY = this.tweenSaveHeight;
- }
- this.tweenInitialX = this.initialX;
- this.tweenInitialY = this.initialY;
- this.tweenTargetX = this.targetX;
- this.tweenTargetY = this.targetY;
- }
- if (this.playmode == -6) {
- this.tweenTargetX = this.tweenSaveWidth;
- this.tweenTargetY = this.tweenSaveHeight;
- }
- } else {
-;
- }
- this.lastKnownValue = this.tweenInitialX;
- this.lastKnownX = this.tweenInitialX;
- this.lastKnownY = this.tweenInitialY;
- this.initiating = parseFloat(this.wait.split(",")[0]);
- this.cooldown = parseFloat(this.wait.split(",")[1]);
- if ((this.initiating < 0) || (isNaN(this.initiating))) this.initiating = 0;
- if ((this.cooldown < 0) || (isNaN(this.cooldown))) this.cooldown = 0;
- if (isCurrent) this.initial = "current";
- if (targetIsCurrent) this.target = "current";
- if (isTargettingObject) this.target = "OBJ";
- };
- function easeOutBounce(t,b,c,d) {
- if ((t/=d) < (1/2.75)) {
- return c*(7.5625*t*t) + b;
- } else if (t < (2/2.75)) {
- return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
- } else if (t < (2.5/2.75)) {
- return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
- } else {
- return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
- }
- }
- behinstProto.easeFunc = function (t, b, c, d)
- {
- switch (this.easing) {
- case 0: // linear
- return c*t/d + b;
- case 1: // easeInQuad
- return c*(t/=d)*t + b;
- case 2: // easeOutQuad
- return -c *(t/=d)*(t-2) + b;
- case 3: // easeInOutQuad
- if ((t/=d/2) < 1) return c/2*t*t + b;
- return -c/2 * ((--t)*(t-2) - 1) + b;
- case 4: // easeInCubic
- return c*(t/=d)*t*t + b;
- case 5: // easeOutCubic
- return c*((t=t/d-1)*t*t + 1) + b;
- case 6: // easeInOutCubic
- if ((t/=d/2) < 1)
- return c/2*t*t*t + b;
- return c/2*((t-=2)*t*t + 2) + b;
- case 7: // easeInQuart
- return c*(t/=d)*t*t*t + b;
- case 8: // easeOutQuart
- return -c * ((t=t/d-1)*t*t*t - 1) + b;
- case 9: // easeInOutQuart
- if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
- return -c/2 * ((t-=2)*t*t*t - 2) + b;
- case 10: // easeInQuint
- return c*(t/=d)*t*t*t*t + b;
- case 11: // easeOutQuint
- return c*((t=t/d-1)*t*t*t*t + 1) + b;
- case 12: // easeInOutQuint
- if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
- return c/2*((t-=2)*t*t*t*t + 2) + b;
- case 13: // easeInCircle
- return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
- case 14: // easeOutCircle
- return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
- case 15: // easeInOutCircle
- if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
- return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
- case 16: // easeInBack
- var s = 0;
- if (s==0) s = 1.70158;
- return c*(t/=d)*t*((s+1)*t - s) + b;
- case 17: // easeOutBack
- var s = 0;
- if (s==0) s = 1.70158;
- return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
- case 18: // easeInOutBack
- var s = 0;
- if (s==0) s = 1.70158;
- if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
- return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
- case 19: //easeInElastic
- var a = 0;
- var p = 0;
- if (t==0) return b; if ((t/=d)==1) return b+c; if (p==0) p=d*.3;
- if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
- case 20: //easeOutElastic
- var a = 0;
- var p = 0;
- if (t==0) return b; if ((t/=d)==1) return b+c; if (p == 0) p=d*.3;
- if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
- case 21: //easeInOutElastic
- var a = 0;
- var p = 0;
- if (t==0) return b;
- if ((t/=d/2)==2) return b+c;
- if (p==0) p=d*(.3*1.5);
- if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
- return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
- case 22: //easeInBounce
- return c - easeOutBounce(d-t, 0, c, d) + b;
- case 23: //easeOutBounce
- return easeOutBounce(t,b,c,d);
- case 24: //easeInOutBounce
- if (t < d/2) return (c - easeOutBounce(d-(t*2), 0, c, d) + b) * 0.5 +b;
- else return easeOutBounce(t*2-d, 0, c, d) * .5 + c*.5 + b;
- case 25: //easeInSmoothstep
- var mt = (t/d) / 2;
- return (2*(mt * mt * (3 - 2*mt)));
- case 26: //easeOutSmoothstep
- var mt = ((t/d) + 1) / 2;
- return ((2*(mt * mt * (3 - 2*mt))) - 1);
- case 27: //easeInOutSmoothstep
- var mt = (t / d);
- return (mt * mt * (3 - 2*mt));
- };
- return 0;
- };
- behinstProto.saveToJSON = function ()
- {
- return {
- "i": this.i,
- "active": this.active,
- "tweened": this.tweened,
- "easing": this.easing,
- "initial": this.initial,
- "target": this.target,
- "duration": this.duration,
- "wait": this.wait,
- "playmode": this.playmode,
- "value": this.value,
- "coord_mode": this.coord_mode,
- "forceInit": this.forceInit,
- "group": this.group,
- "targetObject": this.targetObject,
- "pingpongCounter": this.pingpongCounter,
- "isPaused": this.isPaused,
- "initialX": this.initialX,
- "initialY": this.initialY,
- "targetX": this.targetX,
- "targetY": this.targetY,
- "tweenSaveWidth": this.tweenSaveWidth,
- "tweenSaveHeight": this.tweenSaveHeight,
- "tweenSaveAngle": this.tweenSaveAngle,
- "tweenSaveX": this.tweenSaveX,
- "tweenSaveY": this.tweenSaveY,
- "tweenSaveValue": this.tweenSaveValue,
- "tweenInitialX": this.tweenInitialX,
- "tweenInitialY": this.tweenInitialY,
- "tweenTargetX": this.tweenTargetX,
- "tweenTargetY": this.tweenTargetY,
- "tweenTargetAngle": this.tweenTargetAngle,
- "ratio": this.ratio,
- "reverse": this.reverse,
- "rewindMode": this.rewindMode,
- "doTweenX": this.doTweenX,
- "doTweenY": this.doTweenY,
- "loop": this.loop,
- "initiating": this.initiating,
- "cooldown": this.cooldown,
- "lastPlayMode": this.lastPlayMode,
- "lastKnownValue": this.lastKnownValue,
- "lastKnownX": this.lastKnownX,
- "lastKnownY": this.lastKnownY,
- "onStarted": this.onStarted,
- "onStartedDone": this.onStartedDone,
- "onWaitEnd": this.onWaitEnd,
- "onWaitEndDone": this.onWaitEndDone,
- "onEnd": this.onEnd,
- "onEndDone": this.onEndDone,
- "onCooldown": this.onCooldown,
- "onCooldownDone": this.onCooldownDone
- };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.i = o["i"];
- this.active = o["active"];
- this.tweened = o["tweened"];
- this.easing = o["easing"];
- this.initial = o["initial"];
- this.target = o["target"];
- this.duration = o["duration"];
- this.wait = o["wait"];
- this.playmode = o["playmode"];
- this.value = o["value"];
- this.coord_mode = o["coord_mode"];
- this.forceInit = o["forceInit"];
- this.group = o["group"];
- this.targetObject = o["targetObject"];
- this.pingpongCounter = o["pingpongCounter"];
- this.isPaused = o["isPaused"];
- this.initialX = o["initialX"];
- this.initialY = o["initialY"];
- this.targetX = o["targetX"];
- this.targetY = o["targetY"];
- this.tweenSaveWidth = o["tweenSaveWidth"];
- this.tweenSaveHeight = o["tweenSaveHeight"];
- this.tweenSaveAngle = o["tweenSaveAngle"];
- this.tweenSaveX = o["tweenSaveX"];
- this.tweenSaveY = o["tweenSaveY"];
- this.tweenSaveValue = o["tweenSaveValue"];
- this.tweenInitialX = o["tweenInitialX"];
- this.tweenInitialY = o["tweenInitialY"];
- this.tweenTargetX = o["tweenTargetX"];
- this.tweenTargetY = o["tweenTargetY"];
- this.tweenTargetAngle = o["tweenTargetAngle"];
- this.ratio = o["ratio"];
- this.reverse = o["reverse"];
- this.rewindMode = o["rewindMode"];
- this.doTweenX = o["doTweenX"];
- this.doTweenY = o["doTweenY"];
- this.loop = o["loop"];
- this.initiating = o["initiating"];
- this.cooldown = o["cooldown"];
- this.lastPlayMode = o["lastPlayMode"];
- this.lastKnownValue = o["lastKnownValue"];
- this.lastKnownX = o["lastKnownX"];
- this.lastKnownY = o["lastKnownY"];
- this.onStarted = o["onStarted"];
- this.onStartedDone = o["onStartedDone"];
- this.onWaitEnd = o["onWaitEnd"];
- this.onWaitEndDone = o["onWaitEndDone"]
- this.onEnd = o["onEnd"];
- this.onEndDone = o["onEndDone"];
- this.onCooldown = o["onCooldown"];
- this.onCooldownDone = o["onCooldownDone"];
- this.groupSync();
- };
- behinstProto.tick = function ()
- {
- var dt = this.runtime.getDt(this.inst);
- var isForceStop = (this.i == -1);
- if (!this.active || dt === 0)
- return;
- if (this.i == 0) {
- if (!this.onStarted) {
- this.onStarted = true;
- this.onStartedDone = false;
- this.onWaitEnd = false;
- this.onWaitEndDone = false;
- this.onEnd = false;
- this.onEndDone = false;
- this.onCooldown = false;
- this.onCooldownDone = false;
- this.runtime.trigger(cr.behaviors.lunarray_Tween.prototype.cnds.OnStart, this.inst);
- this.onStartedDone = true;
- }
- }
- if (this.i == -1) {
- this.i = this.initiating + this.duration + this.cooldown;
- } else {
- this.i += dt;
- }
- if (this.i <= this.initiating) {
- return;
- } else {
- if (this.onWaitEnd == false) {
- this.onWaitEnd = true;
- this.runtime.trigger(cr.behaviors.lunarray_Tween.prototype.cnds.OnWaitEnd, this.inst);
- this.onWaitEndDone = true;
- }
- }
- if (this.i <= (this.duration + this.initiating)) {
- var factor = this.easeFunc(this.i-this.initiating, 0, 1, this.duration);
- if (this.tweened == 0) {
- if (this.coord_mode == 1) {
- if (this.inst.x !== this.lastKnownX) {
- this.tweenInitialX += (this.inst.x - this.lastKnownX);
- this.tweenTargetX += (this.inst.x - this.lastKnownX);
- }
- if (this.inst.y !== this.lastKnownY) {
- this.tweenInitialY += (this.inst.y - this.lastKnownY);
- this.tweenTargetY += (this.inst.y - this.lastKnownY);
- }
- } else {
- if (this.inst.x !== this.lastKnownX)
- this.tweenInitialX += (this.inst.x - this.lastKnownX);
- if (this.inst.y !== this.lastKnownY)
- this.tweenInitialY += (this.inst.y - this.lastKnownY);
- }
- this.inst.x = this.tweenInitialX + (this.tweenTargetX - this.tweenInitialX) * factor;
- this.inst.y = this.tweenInitialY + (this.tweenTargetY - this.tweenInitialY) * factor;
- this.lastKnownX = this.inst.x;
- this.lastKnownY = this.inst.y;
- } else if ((this.tweened == 1) || (this.tweened == 2) || (this.tweened == 3)) {
- if (this.inst.width !== this.lastKnownX)
- this.tweenInitialX = this.inst.width;
- if (this.inst.height !== this.lastKnownY)
- this.tweenInitialY = this.inst.height;
- if (this.doTweenX) {
- this.inst.width = this.tweenInitialX + (this.tweenTargetX - this.tweenInitialX) * factor;
- }
- if (this.doTweenY) {
- this.inst.height = this.tweenInitialY + (this.tweenTargetY - this.tweenInitialY) * factor;
- } else {
- if (this.tweened == 1) {
- this.inst.height = this.inst.width * this.ratio;
- }
- }
- this.lastKnownX = this.inst.width;
- this.lastKnownY = this.inst.height;
- } else if (this.tweened == 4) {
- var tangle = this.tweenInitialX + (this.tweenTargetAngle - this.tweenInitialX) * factor;
- if (this.i >= (this.duration + this.initiating))
- tangle = this.tweenTargetAngle;
- this.inst.angle = cr.clamp_angle(tangle);
- } else if (this.tweened == 5) {
- if (this.coord_mode == 1) {
- if (this.inst.opacity !== this.lastKnownX)
- this.tweenInitialX = this.inst.opacity;
- }
- this.inst.opacity = this.tweenInitialX + (this.tweenTargetX - this.tweenInitialX) * factor;
- this.lastKnownX = this.inst.opacity;
- } else if (this.tweened == 6) {
- this.value = this.tweenInitialX + (this.tweenTargetX - this.tweenInitialX) * factor;
- } else if (this.tweened == 7) {
- if (this.coord_mode == 1) {
- if (this.inst.width !== this.lastKnownX)
- this.tweenInitialX = this.inst.width;
- if (this.inst.height !== this.lastKnownY)
- this.tweenInitialY = this.inst.height;
- }
- if (this.doTweenX) this.inst.width = this.tweenInitialX + (this.tweenTargetX - this.tweenInitialX) * factor;
- if (this.doTweenY) this.inst.height = this.tweenInitialY + (this.tweenTargetY - this.tweenInitialY) * factor;
- this.lastKnownX = this.inst.width;
- this.lastKnownY = this.inst.height;
- }
- this.inst.set_bbox_changed();
- }
- if (this.i >= this.duration + this.initiating) {
- this.doEndFrame(isForceStop);
- this.inst.set_bbox_changed();
- if (this.onEnd == false) {
- this.onEnd = true;
- this.runtime.trigger(cr.behaviors.lunarray_Tween.prototype.cnds.OnEnd, this.inst);
- this.onEndDone = true;
- }
- };
- };
- behinstProto.doEndFrame = function (isForceStop)
- {
- switch (this.tweened) {
- case 0: // position
- this.inst.x = this.tweenTargetX;
- this.inst.y = this.tweenTargetY;
- break;
- case 1: // size
- if (this.doTweenX) this.inst.width = this.tweenTargetX;
- if (this.doTweenY) {
- this.inst.height = this.tweenTargetY;
- } else {
- this.inst.height = this.inst.width * this.ratio;
- }
- break;
- case 2: // width
- this.inst.width = this.tweenTargetX;
- break;
- case 3: // height
- this.inst.height = this.tweenTargetY;
- break;
- case 4: // angle
- var tangle = this.tweenTargetAngle;
- this.inst.angle = cr.clamp_angle(tangle);
- this.lastKnownValue = this.inst.angle;
- break;
- case 5: // opacity
- this.inst.opacity = this.tweenTargetX;
- break;
- case 6: // value
- this.value = this.tweenTargetX;
- break;
- case 7: // size
- if (this.doTweenX) this.inst.width = this.tweenTargetX;
- if (this.doTweenY) this.inst.height = this.tweenTargetY;
- break;
- }
- if (this.i >= this.duration + this.initiating + this.cooldown) {
- if (this.playmode == 0) {
- this.active = false;
- this.reverse = false;
- this.i = this.duration + this.initiating + this.cooldown;
- } else if (this.playmode == 1) {
- this.i = 0;
- this.init();
- this.active = true;
- } else if (this.playmode == 2) {
- if (isForceStop) {
- this.reverse = false;
- this.init();
- } else {
- this.reverse = !this.reverse;
- this.i = 0;
- this.init();
- this.active = true;
- }
- } else if (this.playmode == 3) {
- this.runtime.DestroyInstance(this.inst);
- } else if (this.playmode == 4) {
- this.loop = true;
- this.i = 0;
- this.init();
- this.active = true;
- } else if (this.playmode == 5) {
- if (isForceStop) {
- this.reverse = false;
- this.init();
- } else {
- if (this.pingpongCounter <= 0) {
- this.i = this.duration + this.initiating + this.cooldown;
- this.active = false;
- } else {
- if (!this.reverse) {
- this.pingpongCounter -= 1;
- this.reverse = true;
- this.i = 0;
- this.init();
- this.active = true;
- } else {
- this.pingpongCounter -= 1;
- this.reverse = false;
- this.i = 0;
- this.init();
- this.active = true;
- }
- }
- }
- } else if (this.playmode == -6) {
- this.playmode = this.lastPlayMode;
- this.reverse = false;
- this.i = 0;
- this.active = false;
- } else if (this.playmode == 6) {
- this.reverse = false;
- this.i = this.duration + this.initiating + this.cooldown;
- this.active = false;
- }
- }
- if (this.onCooldown == false) {
- this.onCooldown = true;
- this.runtime.trigger(cr.behaviors.lunarray_Tween.prototype.cnds.OnCooldownEnd, this.inst);
- this.onCooldownDone = true;
- }
- }
- behaviorProto.cnds = {};
- var cnds = behaviorProto.cnds;
- cnds.IsActive = function ()
- {
- return this.active;
- };
- cnds.CompareGroupProgress = function (cmp, v)
- {
- var x = [];
- cr.lunarray_tweenGroup[this.group].forEach(function (value) {
- x.push((value.i / (value.duration + value.initiating + value.cooldown)));
- } );
- return cr.do_cmp( Math.min.apply(null, x), cmp, v );
- }
- cnds.CompareProgress = function (cmp, v)
- {
- return cr.do_cmp((this.i / (this.duration + this.initiating + this.cooldown)), cmp, v);
- };
- cnds.OnStart = function ()
- {
- if (this.onStartedDone === false) {
- return this.onStarted;
- }
- };
- cnds.OnWaitEnd = function ()
- {
- if (this.onWaitEndDone === false) {
- return this.onWaitEnd;
- }
- };
- cnds.OnEnd = function (a, b, c)
- {
- if (this.onEndDone === false) {
- return this.onEnd;
- }
- };
- cnds.OnCooldownEnd = function ()
- {
- if (this.onCooldownDone === false) {
- return this.onCooldown;
- }
- };
- behaviorProto.acts = {};
- var acts = behaviorProto.acts;
- acts.SetActive = function (a)
- {
- this.active = (a === 1);
- };
- acts.StartGroup = function (force, sgroup)
- {
- if (sgroup === "") sgroup = this.group;
- var groupReady = (force === 1) || cr.lunarray_tweenGroup[sgroup].every(function(value2) { return !value2.active; } );
- if ( groupReady ) {
- cr.lunarray_tweenGroup[sgroup].forEach(
- function(value) {
- if (force === 1) {
- acts.Force.apply(value);
- } else {
- acts.Start.apply(value);
- }
- }
- );
- }
- }
- acts.StopGroup = function (stopmode, sgroup)
- {
- if (sgroup === "") sgroup = this.group;
- cr.lunarray_tweenGroup[sgroup].forEach( function(value) {
- acts.Stop.apply(value, [stopmode]);
- } );
- }
- acts.ReverseGroup = function (force, rewindMode, sgroup)
- {
- if (sgroup === "") sgroup = this.group;
- var groupReady = (force === 1) || cr.lunarray_tweenGroup[sgroup].every(function(value2) { return !value2.active; } );
- if ( groupReady ) {
- cr.lunarray_tweenGroup[sgroup].forEach(
- function(value) {
- if (force === 1) {
- acts.ForceReverse.apply(value, [rewindMode]);
- } else {
- acts.Reverse.apply(value, [rewindMode]);
- }
- }
- );
- }
- }
- acts.Force = function ()
- {
- this.loop = (this.playmode === 4);
- if (this.playmode == 5) this.pingpongCounter = 1;
- if ((this.playmode == 6) || (this.playmode == -6)) {
- if (this.i < this.duration + this.cooldown + this.initiating) {
- this.reverse = false;
- this.init();
- this.active = true;
- }
- } else {
- this.reverse = false;
- this.i = 0;
- this.init();
- this.active = true;
- }
- };
- acts.ForceReverse = function (rewindMode)
- {
- this.rewindMode = (rewindMode == 1);
- this.loop = (this.playmode === 4);
- if (this.playmode == 5) this.pingpongCounter = 1;
- if ((this.playmode == 6) || (this.playmode == -6)) {
- if (this.i < this.duration + this.cooldown + this.initiating) {
- this.reverse = true;
- this.init();
- this.active = true;
- }
- } else {
- if (rewindMode) {
- if (this.pingpongCounter == 1) {
- if (this.i >= this.duration + this.cooldown + this.initiating) {
- this.reverse = true;
- this.i = 0;
- this.pingpongCounter = 2;
- this.init();
- this.active = true;
- }
- }
- } else {
- this.reverse = true;
- this.i = 0;
- this.init();
- this.active = true;
- }
- }
- };
- acts.Start = function ()
- {
- if (!this.active) {
- this.loop = (this.playmode === 4);
- if (this.playmode == 5) this.pingpongCounter = 1;
- if ((this.playmode == 6) || (this.playmode == -6)) {
- if (this.i < this.duration + this.cooldown + this.initiating) {
- this.reverse = false;
- this.init();
- this.active = true;
- }
- } else {
- this.pingpongCounter = 1;
- this.reverse = false;
- this.i = 0;
- this.init();
- this.active = true;
- }
- }
- };
- acts.Stop = function (stopmode)
- {
- if (this.active) {
- if ((this.playmode == 2) || (this.playmode == 4)) {
- if (this.reverse) {
- this.i = 0;
- } else {
- this.i = -1;
- }
- } else {
- if (stopmode == 1) {
- this.saveState();
- } else if (stopmode == 0) {
- this.i = this.initiating + this.cooldown + this.duration;
- } else {
- this.i = 0;
- }
- }
- this.tick();
- this.active = false;
- }
- };
- acts.Pause = function () {
- if (this.active) {
- this.isPaused = true;
- this.active = false;
- }
- }
- acts.Resume = function () {
- if (this.isPaused) {
- this.active = true;
- this.isPaused = false;
- } else {
- if (!this.active) {
- this.reverse = false;
- this.i = 0;
- this.init();
- this.active = true;
- }
- }
- }
- acts.Reverse = function (rewindMode)
- {
- this.rewindMode = (rewindMode == 1);
- if (!this.active) {
- this.loop = (this.playmode === 4);
- if (this.playmode == 5) this.pingpongCounter = 1;
- if ((this.playmode == 6) || (this.playmode == -6)) {
- if (this.i < this.duration + this.cooldown + this.initiating) {
- this.reverse = true;
- this.init();
- this.active = true;
- }
- } else {
- if (rewindMode) {
- if (this.pingpongCounter == 1) {
- if (this.i >= this.duration + this.cooldown + this.initiating) {
- this.reverse = true;
- this.i = 0;
- this.pingpongCounter = 2;
- this.init();
- this.active = true;
- }
- }
- } else {
- this.reverse = true;
- this.i = 0;
- this.init();
- this.active = true;
- }
- }
- }
- };
- acts.SetDuration = function (x)
- {
- this.duration = x;
- };
- acts.SetWait = function (x)
- {
- this.wait = x;
- this.initiating = parseFloat(this.wait.split(",")[0]);
- this.cooldown = parseFloat(this.wait.split(",")[1]);
- if ((this.initiating < 0) || (isNaN(this.initiating))) this.initiating = 0;
- if ((this.cooldown < 0) || (isNaN(this.cooldown))) this.cooldown = 0;
- };
- acts.SetTarget = function (x)
- {
- if (typeof(x) == "string") {
- this.target = x;
- this.targetX = parseFloat(x.split(",")[0]);
- this.targetY = parseFloat(x.split(",")[1]);
- } else {
- this.target = x;
- this.targetX = x;
- }
- if (!this.active) {
- this.init();
- } else {
- }
- };
- acts.SetTargetObject = function (obj)
- {
- if (!obj)
- return;
- var otherinst = obj.getFirstPicked();
- if (!otherinst)
- return;
- this.targetObject = otherinst;
- this.target = "OBJ";
- };
- acts.SetTargetX = function (x)
- {
- if ((this.tweened == 2) || (this.tweened == 3) || (this.tweened == 4) || (this.tweened == 5) || (this.tweened == 6)) {
- if (typeof(x) == "string") {
- this.target = parseFloat(x.split(",")[0]);
- } else {
- this.target = ""+x+","+this.targetY;
- }
- this.targetX = this.target;
- } else {
- var currY = this.target.split(",")[1];
- this.target = String(x) + "," + currY;
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- }
- if (!this.active) {
- this.saveState();
- this.init();
- } else {
- }
- };
- acts.SetTargetY = function (x)
- {
- if ((this.tweened == 2) || (this.tweened == 3) || (this.tweened == 4) || (this.tweened == 5) || (this.tweened == 6)) {
- if (typeof(x) == "string") {
- this.target = parseFloat(x)+"";
- } else {
- this.target = this.targetX+","+x;
- }
- this.targetX = this.target;
- } else {
- var currX = this.target.split(",")[0];
- this.target = currX + "," + String(x);
- this.targetX = parseFloat(this.target.split(",")[0]);
- this.targetY = parseFloat(this.target.split(",")[1]);
- }
- if (!this.active) {
- this.saveState();
- this.init();
- } else {
- }
- };
- acts.SetInitial = function (x)
- {
- if (typeof(x) == "string") {
- this.initial = x;
- this.initialX = parseFloat(x.split(",")[0]);
- this.initialY = parseFloat(x.split(",")[1]);
- } else {
- this.initial = ""+x;
- this.initialX = x;
- }
- if (this.tweened == 6) {
- this.value = this.initialX;
- }
- if (!this.active) {
- this.saveState();
- this.init();
- } else {
- }
- };
- acts.SetInitialX = function (x)
- {
- if ((this.tweened == 2) || (this.tweened == 3) || (this.tweened == 4) || (this.tweened == 5) || (this.tweened == 6)) {
- if (typeof(x) == "string") {
- this.initial = parseFloat(x);
- } else {
- this.initial = ""+x+","+this.initialY;
- }
- this.initialX = this.initial;
- } else {
- if (this.initial == "") this.initial = "current";
- if (this.initial == "current") {
- var currY = this.tweenSaveY;
- } else {
- var currY = this.initial.split(",")[1];
- }
- this.initial = String(x) + "," + currY;
- this.initialX = parseFloat(this.initial.split(",")[0]);
- this.initialY = parseFloat(this.initial.split(",")[1]);
- }
- if (this.tweened == 6) {
- this.value = this.initialX;
- }
- if (!this.active) {
- this.saveState();
- this.init();
- } else {
- }
- };
- acts.SetInitialY = function (x)
- {
- if ((this.tweened == 2) || (this.tweened == 3) || (this.tweened == 4) || (this.tweened == 5) || (this.tweened == 6)) {
- if (typeof(x) == "string") {
- this.initial = parseFloat(x);
- } else {
- this.initial = ""+this.initialX+","+x;
- }
- this.initialX = this.initial;
- } else {
- if (this.initial == "") this.initial = "current";
- if (this.initial == "current") {
- var currX = this.tweenSaveX;
- } else {
- var currX = this.initial.split(",")[0];
- }
- this.initial = currX + "," + String(x);
- this.initialX = parseFloat(this.initial.split(",")[0]);
- this.initialY = parseFloat(this.initial.split(",")[1]);
- }
- if (!this.active) {
- this.saveState();
- this.init();
- } else {
- }
- };
- acts.SetValue = function (x)
- {
- this.value = x;
- };
- acts.SetTweenedProperty = function (m)
- {
- this.tweened = m;
- };
- acts.SetEasing = function (w)
- {
- this.easing = w;
- };
- acts.SetPlayback = function (x)
- {
- this.playmode = x;
- };
- acts.SetParameter = function (tweened, playmode, easefunction, initial, target, duration, wait, cmode)
- {
- this.tweened = tweened;
- this.playmode = playmode;
- this.easing = easefunction;
- acts.SetInitial.apply(this, [initial]);
- acts.SetTarget.apply(this, [target]);
- acts.SetDuration.apply(this, [duration]);
- acts.SetWait.apply(this, [wait]);
- this.coord_mode = cmode;
- this.saveState();
- };
- behaviorProto.exps = {};
- var exps = behaviorProto.exps;
- exps.Progress = function (ret)
- {
- ret.set_float(this.i / (this.duration + this.initiating + this.cooldown));
- };
- exps.ProgressTime = function (ret)
- {
- ret.set_float(this.i);
- };
- exps.Duration = function (ret)
- {
- ret.set_float(this.duration);
- };
- exps.Initiating = function (ret)
- {
- ret.set_float(this.initiating);
- };
- exps.Cooldown = function (ret)
- {
- ret.set_float(this.cooldown);
- };
- exps.Target = function (ret)
- {
- ret.set_string(this.target);
- };
- exps.Value = function (ret)
- {
- ret.set_float(this.value);
- };
- exps.isPaused = function (ret)
- {
- ret.set_int(this.isPaused ? 1: 0);
- };
-}());
cr.getObjectRefTable = function () { return [
cr.plugins_.Audio,
cr.plugins_.Browser,
cr.plugins_.Function,
+ cr.plugins_.SenaPlugin,
cr.plugins_.SpriteFontPlus,
- cr.plugins_.Text,
cr.plugins_.Sprite,
- cr.plugins_.TDVplugin,
cr.plugins_.Touch,
- cr.behaviors.Rex_MoveTo,
cr.behaviors.Fade,
cr.behaviors.DragnDrop,
- cr.behaviors.Pin,
+ cr.behaviors.Rex_MoveTo,
cr.behaviors.Sin,
- cr.behaviors.lunarray_Tween,
- cr.plugins_.Function.prototype.cnds.OnFunction,
- cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPosByDeltaXY,
+ cr.behaviors.Pin,
cr.system_object.prototype.cnds.OnLayoutStart,
- cr.plugins_.Sprite.prototype.acts.SetVisible,
+ cr.plugins_.SenaPlugin.prototype.acts.Load,
cr.system_object.prototype.acts.SetLayerVisible,
- cr.plugins_.Browser.prototype.acts.ExecJs,
- cr.behaviors.Pin.prototype.acts.Pin,
- cr.system_object.prototype.acts.Wait,
- cr.plugins_.Text.prototype.acts.SetText,
- cr.plugins_.Browser.prototype.exps.ExecJS,
- cr.plugins_.Touch.prototype.cnds.OnTouchEnd,
- cr.plugins_.Audio.prototype.acts.Play,
- cr.system_object.prototype.cnds.LayerVisible,
- cr.behaviors.Rex_MoveTo.prototype.cnds.IsMoving,
- cr.plugins_.Function.prototype.acts.CallFunction,
- cr.behaviors.Rex_MoveTo.prototype.cnds.OnHitTarget,
- cr.behaviors.lunarray_Tween.prototype.acts.Force,
- cr.behaviors.lunarray_Tween.prototype.cnds.OnEnd,
- cr.system_object.prototype.acts.GoToLayout,
- cr.plugins_.TDVplugin.prototype.cnds.OnStart,
- cr.system_object.prototype.acts.SetVar,
- cr.plugins_.Sprite.prototype.acts.SetBoolInstanceVar,
- cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
- cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnLoad,
+ cr.plugins_.Browser.prototype.acts.ConsoleLog,
+ cr.plugins_.SenaPlugin.prototype.exps.getGuide,
+ cr.plugins_.SenaPlugin.prototype.acts.Start,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnStart,
+ cr.plugins_.SenaPlugin.prototype.exps.getQuestionType,
+ cr.plugins_.SenaPlugin.prototype.exps.getQuestionValue,
+ cr.plugins_.SenaPlugin.prototype.exps.getRequestType,
+ cr.plugins_.SenaPlugin.prototype.exps.getRequestValue,
+ cr.plugins_.SenaPlugin.prototype.exps.getOptionsCount,
+ cr.plugins_.SenaPlugin.prototype.exps.getHintCount,
cr.plugins_.Sprite.prototype.acts.Destroy,
- cr.plugins_.Text.prototype.acts.Destroy,
- cr.system_object.prototype.cnds.Repeat,
- cr.system_object.prototype.exps.loopindex,
- cr.system_object.prototype.acts.CreateObject,
+ cr.system_object.prototype.acts.SetVar,
+ cr.system_object.prototype.exps["int"],
+ cr.behaviors.Pin.prototype.acts.Pin,
+ cr.plugins_.SpriteFontPlus.prototype.acts.SetText,
+ cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
cr.plugins_.Sprite.prototype.exps.X,
cr.plugins_.Sprite.prototype.exps.Y,
- cr.plugins_.Sprite.prototype.exps.Width,
- cr.plugins_.Text.prototype.acts.SetFontSize,
- cr.system_object.prototype.cnds.Compare,
- cr.system_object.prototype.cnds.Else,
- cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
- cr.behaviors.DragnDrop.prototype.cnds.OnDragStart,
- cr.plugins_.Sprite.prototype.acts.MoveToTop,
- cr.plugins_.Sprite.prototype.cnds.IsOverlapping,
- cr.plugins_.Text.prototype.acts.MoveToTop,
- cr.behaviors.DragnDrop.prototype.cnds.OnDrop,
- cr.plugins_.Sprite.prototype.cnds.IsBoolInstanceVarSet,
cr.plugins_.Sprite.prototype.acts.SetPos,
- cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPos,
- cr.system_object.prototype.cnds.Every,
- cr.system_object.prototype.cnds.CompareVar,
- cr.system_object.prototype.cnds.EveryTick,
+ cr.plugins_.SenaPlugin.prototype.acts.CalcObjectPositions,
+ cr.plugins_.Sprite.prototype.exps.Width,
+ cr.system_object.prototype.cnds.Repeat,
+ cr.system_object.prototype.exps.loopindex,
+ cr.plugins_.SenaPlugin.prototype.exps.getHintType,
+ cr.plugins_.SenaPlugin.prototype.exps.getHintValue,
+ cr.system_object.prototype.acts.CreateObject,
+ cr.plugins_.SenaPlugin.prototype.exps.getPosXbyIndex,
+ cr.plugins_.SenaPlugin.prototype.exps.getPosYbyIndex,
+ cr.system_object.prototype.cnds.Compare,
+ cr.plugins_.Sprite.prototype.acts.SetBoolInstanceVar,
+ cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
+ cr.system_object.prototype.cnds.Else,
+ cr.plugins_.Sprite.prototype.acts.SetY,
+ cr.plugins_.SenaPlugin.prototype.exps.getOptionsType,
+ cr.plugins_.SenaPlugin.prototype.exps.getOptionsValue,
cr.plugins_.Touch.prototype.cnds.OnTouchObject,
cr.plugins_.Sprite.prototype.cnds.IsVisible,
+ cr.system_object.prototype.cnds.CompareVar,
+ cr.plugins_.Audio.prototype.acts.Play,
+ cr.plugins_.SenaPlugin.prototype.acts.PauseGame,
+ cr.behaviors.DragnDrop.prototype.acts.SetEnabled,
+ cr.plugins_.Function.prototype.acts.CallFunction,
+ cr.system_object.prototype.acts.Wait,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnCorrect,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnWrong,
+ cr.plugins_.SenaPlugin.prototype.acts.ResumeGame,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnPause,
+ cr.plugins_.SenaPlugin.prototype.cnds.OnResume,
+ cr.system_object.prototype.cnds.EveryTick,
+ cr.plugins_.SenaPlugin.prototype.exps.getTimeLimit,
+ cr.system_object.prototype.exps.max,
+ cr.plugins_.SenaPlugin.prototype.exps.getElapsedTime,
cr.system_object.prototype.cnds.TriggerOnce,
- cr.plugins_.SpriteFontPlus.prototype.acts.SetText,
- cr.behaviors.Rex_MoveTo.prototype.acts.KENSetTargetPos,
- cr.system_object.prototype.cnds.For
+ cr.plugins_.SpriteFontPlus.prototype.acts.Destroy,
+ cr.behaviors.Fade.prototype.acts.StartFade,
+ cr.plugins_.SenaPlugin.prototype.acts.Finish,
+ cr.plugins_.Function.prototype.cnds.OnFunction,
+ cr.system_object.prototype.cnds.For,
+ cr.system_object.prototype.cnds.PickByComparison,
+ cr.system_object.prototype.exps.left,
+ cr.system_object.prototype.exps.len,
+ cr.plugins_.Sprite.prototype.cnds.CompareY,
+ cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPos,
+ cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPosOnObject,
+ cr.plugins_.Sprite.prototype.cnds.CompareFrame,
+ cr.plugins_.Audio.prototype.acts.SetSilent,
+ cr.system_object.prototype.cnds.LayerVisible,
+ cr.behaviors.DragnDrop.prototype.cnds.OnDragStart,
+ cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
+ cr.plugins_.Sprite.prototype.cnds.IsOverlapping,
+ cr.plugins_.Sprite.prototype.acts.MoveToTop,
+ cr.plugins_.SpriteFontPlus.prototype.acts.MoveToTop,
+ cr.behaviors.DragnDrop.prototype.cnds.OnDrop,
+ cr.plugins_.Sprite.prototype.cnds.IsBoolInstanceVarSet,
+ cr.plugins_.Sprite.prototype.cnds.PickDistance,
+ cr.behaviors.Rex_MoveTo.prototype.acts.SetMaxSpeed,
+ cr.system_object.prototype.acts.AddVar,
+ cr.behaviors.DragnDrop.prototype.cnds.IsDragging,
+ cr.plugins_.Touch.prototype.exps.X,
+ cr.plugins_.Touch.prototype.exps.Y,
+ cr.plugins_.Sprite.prototype.acts.SetVisible
];};
diff --git a/G120-sequence/data.js b/G120-sequence/data.js
new file mode 100644
index 0000000..fa9b88c
--- /dev/null
+++ b/G120-sequence/data.js
@@ -0,0 +1 @@
+{"project": [null,null,[[0,true,false,false,false,false,false,false,false,false],[1,true,false,false,false,false,false,false,false,false],[2,true,false,false,false,false,false,false,false,false],[3,true,false,false,false,false,false,false,false,false],[4,false,true,true,true,true,true,true,true,true],[5,false,true,true,true,true,true,true,true,false],[6,true,false,false,false,false,false,false,false,false]],[["t0",3,false,[],0,0,null,null,[],false,false,394152958375253,[],null,["G2800S1T30"]],["t1",1,false,[],0,0,null,null,[],false,false,181015701933739,[],null,[]],["t2",5,false,[],0,0,null,[["Default",5,false,1,0,false,266653407798345,[["images/btn_check-sheet0.png",17703,0,0,165,75,1,0.5030303001403809,0.5066666603088379,[],[],0]]]],[],false,false,870372553390403,[],null],["t3",5,false,[],0,0,null,[["Default",5,false,1,0,false,644390976254011,[["images/wrong-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,726240664871372,[],null],["t4",6,false,[],0,0,null,null,[],false,false,288430412484243,[],null,[1]],["t5",5,false,[],0,0,null,[["Default",5,false,1,0,false,974942116247628,[["images/pause-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,829278278494442,[],null],["t6",5,false,[],0,0,null,[["Default",5,false,1,0,false,830476950235748,[["images/pause-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,250461366236378,[],null],["t7",5,false,[839027338172447,370467464601183,403859397610033],1,0,null,[["Default",0,false,1,0,false,201845729772152,[["images/slot-sheet0.png",36041,1,1,200,75,1,0.5,0.5066666603088379,[],[],0],["images/slot-sheet0.png",36041,1,78,200,75,1,0.5,0.4933333396911621,[],[],0],["images/slot-sheet0.png",36041,1,155,200,75,1,0.4350000023841858,0.5199999809265137,[],[],0]]]],[["Fade",7,588103285968005]],false,false,530929310100717,[],null],["t8",5,false,[401281652261798,308058330719086,937883104346632,243525000976275,435711195864159],3,0,null,[["Default",5,false,1,0,false,344548683716056,[["images/slot-sheet0.png",36041,1,78,200,75,1,0.5,0.4933333396911621,[],[],0]]]],[["DragDrop",8,551257499299552],["Fade",7,430149822241515],["MoveTo",9,551694077436381]],false,false,515230787966511,[],null],["t9",2,false,[],0,0,null,null,[],false,false,825652157577718,[],null,[]],["t10",4,false,[],0,0,["images/txt_texttimer.png",94512,0],null,[],false,false,428453985749595,[],null],["t11",4,false,[],0,0,["images/txt_worditem.png",94801,0],null,[],false,false,125516006976486,[],null],["t12",4,false,[],0,0,["images/txt_texttimer.png",94512,0],null,[],false,false,680183373657896,[],null],["t13",5,false,[],0,0,null,[["Default",5,false,1,0,false,943124209669759,[["images/5sosarahtakesoff-sheet0.png",1099565,0,0,1400,900,1,0.5,0.5,[],[],1]]]],[],false,false,663734962307467,[],null],["t14",5,false,[],0,0,null,[["Default",5,false,1,0,false,174194635978617,[["images/senaaikhoi-sheet0.png",230528,0,0,1145,446,1,0.4995633065700531,0.4977578520774841,[],[],0]]]],[],false,false,577948289650662,[],null],["t15",5,false,[],0,0,null,[["Default",0,false,1,0,false,329974099612225,[["images/checker_wrong_correct-sheet0.png",10219,0,0,140,140,1,0.5,0.5,[],[-0.3642860054969788,-0.3642860054969788,0,-0.4357143044471741,0.3642860054969788,-0.3642860054969788,0.3999999761581421,0,0.3142859935760498,0.3142859935760498,0,0.442857027053833,-0.2928569912910461,0.2928569912910461,-0.3857139945030212,0],0],["images/checker_wrong_correct-sheet1.png",7978,0,0,140,140,1,0.5,0.5,[],[-0.357142984867096,-0.357142984867096,0,-0.4357143044471741,0.357142984867096,-0.357142984867096,0.3857139945030212,0,0.3642860054969788,0.3642860054969788,0,0.4142860174179077,-0.2857140004634857,0.2857139706611633,-0.3857139945030212,0],0]]]],[],false,false,246032193737445,[],null],["t16",0,false,[],0,0,null,null,[],false,false,396522085041537,[],null,[0,0,0,1,1,600,600,10000,1]],["t17",5,false,[],0,0,null,[["Default",5,false,1,0,false,857466576876240,[["images/btn_setting-sheet0.png",13202,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[-0.3656864762306213,-0.3547005355358124,-0.006272494792938232,-0.5028490424156189,0.355585515499115,-0.3547005355358124,0.485169529914856,-0.005494534969329834,0.3604755401611328,0.349002480506897,-0.006272494792938232,0.4865684509277344,-0.3681314587593079,0.3463574647903442,-0.4977155327796936,-0.005494534969329834],0]]]],[],false,false,444899307061590,[],null],["t18",5,false,[],0,0,null,[["Default",5,false,1,0,false,922486781068681,[["images/panel-sheet0.png",105765,0,0,815,474,1,0.5141104459762573,0.4852320551872253,[],[-0.4453988373279572,0.4156119227409363,-0.5067484974861145,-5.960464477539063e-008,-0.433128833770752,-0.3945147395133972,-4.172325134277344e-007,-0.4704641699790955,0.4184045791625977,-0.3691980540752411,0.4797545671463013,-5.960464477539063e-008,0.4294475317001343,0.3881859183311462,-4.172325134277344e-007,0.5084389448165894],0]]]],[],false,false,150393696478915,[],null],["t19",4,false,[],0,0,["images/txt_question.png",192019,0],null,[],false,false,389192760965508,[],null],["t20",5,false,[637523801130517,567457434227301],1,0,null,[["Default",5,false,1,0,false,177577261579169,[["images/btn_pause-sheet0.png",11757,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[-0.365747481584549,-0.3577375411987305,-0.005050480365753174,-0.5028560161590576,0.3556455373764038,-0.3577375411987305,0.4899744987487793,-0.006813526153564453,0.3581334948539734,0.34938645362854,-0.005050480365753174,0.4892284870147705,-0.365747481584549,0.3467484712600708,-0.4975878000259399,-0.006813526153564453],0]]]],[["MoveTo",9,345261300394347]],false,false,680660539195378,[],null],["t21",5,false,[546775332106909,966775272495183],1,0,null,[["Default",0,false,1,0,false,632596314970396,[["images/btn_music-sheet0.png",13358,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[],0],["images/btn_music-sheet1.png",14207,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[],0]]]],[["MoveTo",9,561713266057788]],false,false,470943728107764,[],null],["t22",5,false,[],0,0,null,[["Default",5,false,1,0,false,804798480075980,[["images/panel_pause-sheet0.png",168,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,103999013142366,[],null],["t23",5,false,[],1,0,null,[["Default",5,false,1,0,false,794524614026990,[["images/layer-sheet0.png",111520,0,0,400,376,1,0.5,0.5,[],[-0.362500011920929,-0.3537229895591736,0,-0.5,0.362500011920929,-0.3537229895591736,0.497499942779541,0,0.3650000095367432,0.3563830256462097,0,0.5,-0.3650000095367432,0.3563830256462097,-0.5,0],0]]]],[["Sine",10,152768910804631]],false,false,822735679292648,[],null],["t24",5,false,[],0,0,null,[["Default",5,false,1,0,false,185281331107930,[["images/newwordpng-sheet0.png",166389,0,0,500,341,1,0.5,0.5014662742614746,[],[-0.3939999938011169,-0.3460412621498108,0,-0.4398826658725739,0.1480000019073486,0.01466274261474609,0.2919999957084656,-0.00293228030204773,0.4660000205039978,0.4486806988716126,0,0.4721407294273377,-0.4620000123977661,0.4428157210350037,-0.2820000052452087,-0.00293228030204773],0]]]],[],false,false,139959116973831,[],null],["t25",4,true,[],1,0,null,null,[["Pin",11,693926857619114]],false,false,154178255437462,[],null],["t26",5,true,[],0,0,null,null,[],false,false,909098946188328,[],null]],[[25,19,12,10,11],[26,21,20,17,23]],[["Layout 1",1200,1200,false,"Event sheet 1",148229480160171,[["BG",0,977906834634586,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600,600,0,1946.035888671875,1251.023071289063,0,0,1,0.5,0.5,0,0,[]],13,13,[],[],[0,"Default",0,1]]],[]],["Main",1,715835324311419,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600.5625,863,0,185.6243591308594,84.37471008300781,0,0,1,0.5030303001403809,0.5066666603088379,0,0,[]],2,2,[],[],[0,"Default",0,1]],[[998,-788,0,250,250,0,0,1,0.5,0.5,0,0,[]],3,3,[],[],[0,"Default",0,1]],[[314,-701,0,58,49,0,0,1,0.5,0.5,0,0,[]],5,5,[],[],[0,"Default",0,1]],[[313,-632,0,58.32666778564453,58.32666778564453,0,0,1,0.5,0.5,0,0,[]],6,6,[],[],[0,"Default",0,1]],[[209,-866,0,200,75,0,0,1,0.5,0.5066666603088379,0,0,[]],7,7,[[0],[""],[0]],[[0,0,0,2,1]],[0,"Default",0,1]],[[-35,-863,0,200,75,0,0,1,0.5,0.4933333396911621,0,0,[]],8,8,[[""],[0],[0],[-1],[0]],[[0,1],[0,0,0,2,1],[1,1200,0,0]],[0,"Default",0,1]],[[668,-675,0,160.2111206054688,55.53988647460938,0,0,1,0.5,0.5,0,0,[]],11,11,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","Text",0.5,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[474,-928,0,160.2109985351563,55.54000091552734,0,0,1,0.5,0.5,0,0,[]],12,12,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","Text",0.5,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[1052,70,0,255.0779113769531,99.35787963867188,0,0,1,0.4995633065700531,0.4977578520774841,0,0,[]],14,14,[],[],[0,"Default",0,1]],[[1080,72,0,132,77,0,0,1,0.5,0.5,0,0,[]],10,10,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","TIME",0.7,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[109,-653,0,140,140,0,0,1,0.5,0.5,0,0,[]],15,15,[],[],[0,"Default",0,1]],[[610.5263671875,400,0,746,299,0,0,1,0.5141104459762573,0.4852320551872253,0,0,[]],18,18,[],[],[0,"Default",0,1]],[[598.5263671875,411,0,642,205,0,0,1,0.5,0.5,0,0,[]],19,19,[],[[]],[73,98,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","Sắp xếp các từ sau thành câu đúng",0.85,0,1,1,1,0,0,0,"{\"\"c2array\"\":true,\"\"size\"\":[2,45,1],\"\"data\"\":[[[20],[11],[13],[14],[15],[16],[18],[19],[21],[22],[23],[24],[25],[26],[29],[30],[31],[32],[33],[34],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[48],[49],[50],[51],[52],[53],[54],[56],[57],[59],[62],[69],[71]],[[\"\" \"\"],[\"\"|\"\"],[\"\"il\"\"],[\"\"I.:'\"\"],[\"\";!\"\"],[\"\",ỊỈịỉ\"\"],[\"\"Ííì\"\"],[\"\"`Ì\"\"],[\"\")\"\"],[\"\"(/\"\"],[\"\"[\"\"],[\"\"j]\"\"],[\"\"-\"\"],[\"\"°\"\"],[\"\"t1ĩ\"\"],[\"\"\\\"\"Ĩ\"\"],[\"\"r\"\"],[\"\"f\"\"],[\"\"*\"\"],[\"\"ẺẸẼỆỄ\"\"],[\"\"sảạăằắặẳẵậẫ\"\"],[\"\"kx\"\"],[\"\"Jhnuẻẹẽệễúùụủũ\"\"],[\"\"v7?+=<>Ể\"\"],[\"\"Faceyz0238áàãâéèêý\"\"],[\"\"L569_~$ẩ\"\"],[\"\"bdgopqểóòõô\"\"],[\"\"P#ọỏộỗỳỵỷỹ\"\"],[\"\"EXÉÈÊỀẾầềổ\"\"],[\"\"S4€ỤỦŨ\"\"],[\"\"Y£Ýấđơờớợởỡ\"\"],[\"\"BNRỲỴỶỸế\"\"],[\"\"DHKTUÚÙồưừứựửữ\"\"],[\"\"VZố\"\"],[\"\"C\"\"],[\"\"AÁÀÃÂ\"\"],[\"\"&\"\"],[\"\"GMỌỎỒỘỔỖ\"\"],[\"\"OẢẠĂẰẮẶẲẴẦẤẬẨẪĐÓÒÕÔỐ\"\"],[\"\"ƯỪỨỰỬỮ\"\"],[\"\"Q\"\"],[\"\"mwƠỜỚỢỞỠ\"\"],[\"\"%\"\"],[\"\"W\"\"],[\"\"@\"\"]]]}",-1]],[[1136.894897460938,1055.94287109375,0,82.66699981689453,75.98699951171875,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],20,20,[[0],[0]],[[1,400,0,0]],[0,"Default",0,1]],[[1136.535278320313,964.1973876953125,0,82.66699981689453,75.98699951171875,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],21,21,[[0],[0]],[[1,400,0,0]],[0,"Default",0,1]],[[1137.084106445313,1146.424194335938,0,82.66677093505859,75.98662567138672,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],17,17,[],[],[0,"Default",0,1]]],[]],["Pause",2,621954870190361,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600,600,0,1946.036010742188,1251.02294921875,0,0,1,0.5,0.5,0,0,[]],22,22,[],[],[0,"Default",0,1]],[[600,600,0,400,376,0,0,1,0.5,0.5,0,0,[]],23,23,[],[[1,2,0,3,0,0,0,50,0]],[0,"Default",0,1]]],[]],["Logo",3,899027236628199,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[110,77,0,195.7390747070313,133.4940490722656,0,0,1,0.5,0.5014662742614746,0,0,[]],24,24,[],[],[0,"Default",0,1]]],[]]],[],[]]],[["Event sheet 1",[[1,"Paused",0,0,false,false,881036884152158,false],[2,"DrapDrop",false],[1,"end",0,-1,false,false,348658772353398,false],[1,"isTimeUp",0,0,false,false,617056362802034,false],[1,"timeLeft",0,0,false,false,670843326082385,false],[1,"answer",1,"",false,false,538561721013949,false],[0,null,false,null,421297551205104,[[-1,12,null,1,false,false,false,438843515576193,false]],[[0,13,null,551138518888793,false],[-1,14,null,392038834754127,false,[[5,[0,2]],[3,0]]]]],[0,null,false,null,432411265738905,[[0,15,null,1,false,false,false,913106290597646,false]],[[1,16,null,260483465573520,false,[[3,0],[7,[2,"Load dữ liệu xong"]]]],[1,16,null,330854144982241,false,[[3,0],[7,[20,0,17,true,null]]]]],[[0,null,false,null,122100426567399,[],[[0,18,null,458181517098292,false]]]]],[0,null,false,null,495673204159818,[[0,19,null,1,false,false,false,157454832331304,false]],[[1,16,null,816803828558793,false,[[3,0],[7,[10,[10,[10,[2,"Question :"],[20,0,20,true,null]],[2," with value : "]],[20,0,21,true,null]]]]],[1,16,null,585706784629547,false,[[3,0],[7,[10,[10,[10,[2,"Request :"],[20,0,22,true,null]],[2," with value : "]],[20,0,23,true,null]]]]],[1,16,null,103090682922262,false,[[3,0],[7,[10,[2,"Options Count :"],[20,0,24,false,null]]]]],[1,16,null,460050924307031,false,[[3,0],[7,[10,[2,"Hint Count :"],[20,0,25,false,null]]]]],[7,26,null,227093858363506,false],[8,26,null,601277174090980,false],[-1,27,null,623599131030475,false,[[11,"isTimeUp"],[7,[0,0]]]],[-1,27,null,425755884896431,false,[[11,"end"],[7,[19,28,[[20,0,24,false,null]]]]]],[19,29,"Pin",210783341114782,false,[[4,18],[3,0]]],[10,29,"Pin",636254900159958,false,[[4,14],[3,0]]],[19,30,null,808593987399542,false,[[7,[20,0,21,true,null]]]],[20,31,null,756761854102448,false,[[10,0],[7,[20,20,32,false,null]]]],[20,31,null,843231659647898,false,[[10,1],[7,[20,20,33,false,null]]]],[20,34,null,429067541495196,false,[[0,[20,17,32,false,null]],[0,[20,17,33,false,null]]]],[21,31,null,312955471850139,false,[[10,0],[7,[20,21,32,false,null]]]],[21,31,null,725880314927928,false,[[10,1],[7,[20,21,33,false,null]]]],[21,34,null,588637745430653,false,[[0,[20,17,32,false,null]],[0,[20,17,33,false,null]]]]],[[0,null,false,null,278599510819277,[],[[0,35,null,505162364268873,false,[[0,[19,28,[[20,0,25,false,null]]]],[0,[20,7,36,false,null]],[0,[0,5]],[0,[0,1200]],[0,[0,0]],[0,[0,100]],[1,[2,"slot"]],[0,[0,0]]]]],[[0,null,false,null,452078189778132,[[-1,37,null,0,true,false,false,488889777784546,false,[[0,[19,28,[[20,0,25,false,null]]]]]]],[[1,16,null,239886316843096,false,[[3,0],[7,[10,[10,[10,[10,[10,[2,"Hint "],[19,38]],[2," : "]],[20,0,39,true,null]],[2," with value : "]],[20,0,40,false,null,[[19,38]]]]]]],[-1,41,null,371942430718793,false,[[4,7],[5,[0,1]],[0,[20,0,42,false,null,[[19,38]]]],[0,[4,[20,0,43,false,null,[[19,38]]],[0,650]]]]],[7,31,null,933941275549609,false,[[10,0],[7,[19,38]]]],[7,31,null,380164134533232,false,[[10,1],[7,[20,0,40,false,null,[[19,38]]]]]]],[[0,null,false,null,698796573985720,[[-1,44,null,0,false,false,false,410553190492367,false,[[7,[20,0,40,false,null,[[19,38]]]],[8,1],[7,[2,"_"]]]]],[[7,45,null,847566670403732,false,[[10,2],[3,1]]],[-1,41,null,521667370636870,false,[[4,12],[5,[0,1]],[0,[20,7,32,false,null]],[0,[20,7,33,false,null]]]],[12,29,"Pin",361028315192679,false,[[4,7],[3,0]]],[12,30,null,466267976699500,false,[[7,[21,7,true,null,1]]]],[7,46,null,354611702724504,false,[[0,[0,1]]]]]],[0,null,false,null,848543107448972,[[-1,47,null,0,false,false,false,386888311054006,false]],[[7,45,null,590812225579568,false,[[10,2],[3,0]]]]]]]]],[0,null,false,null,822104816469346,[],[[0,35,null,737719939649407,false,[[0,[19,28,[[20,0,24,false,null]]]],[0,[20,8,36,false,null]],[0,[0,5]],[0,[0,1200]],[0,[0,0]],[0,[0,100]],[1,[2,"word"]],[0,[0,0]]]],[2,48,null,256704970269789,false,[[0,[4,[20,0,43,false,null,[[0,0]]],[0,700]]]]]],[[0,null,false,null,441467613146144,[[-1,37,null,0,true,false,false,218190693390519,false,[[0,[19,28,[[20,0,24,false,null]]]]]]],[[1,16,null,901551014325770,false,[[3,0],[7,[10,[10,[10,[10,[10,[2,"Options "],[19,38]],[2," : "]],[20,0,49,true,null]],[2," with value : "]],[20,0,50,true,null,[[19,38]]]]]]],[-1,41,null,722355474670048,false,[[4,8],[5,[0,1]],[0,[20,0,42,false,null,[[19,38]]]],[0,[4,[20,0,43,false,null,[[19,38]]],[0,700]]]]],[8,31,null,424845902591780,false,[[10,0],[7,[20,0,50,true,null,[[19,38]]]]]],[8,31,null,732477610518970,false,[[10,3],[7,[0,-1]]]],[8,31,null,972534679995256,false,[[10,1],[7,[20,8,32,false,null]]]],[8,31,null,955022957314574,false,[[10,2],[7,[20,8,33,false,null]]]],[-1,41,null,820542104698850,false,[[4,11],[5,[0,1]],[0,[20,8,32,false,null]],[0,[20,8,33,false,null]]]],[11,29,"Pin",165265909130423,false,[[4,8],[3,0]]],[11,30,null,752256115955919,false,[[7,[21,8,true,null,0]]]]]]]]]],[0,null,false,null,391531229850255,[[4,51,null,1,false,false,false,541795463553529,false,[[4,2]]],[2,52,null,0,false,false,false,463624702778654,false],[-1,53,null,0,false,false,false,211208220731414,false,[[11,"Paused"],[8,0],[7,[0,0]]]]],[[16,54,null,933729384541080,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[0,55,null,256977907477815,false],[8,56,"DragDrop",500676445420163,false,[[3,0]]],[-1,27,null,392747038186299,false,[[11,"answer"],[7,[2,""]]]],[9,57,null,286145656469424,false,[[1,[2,"currentAnswer"]],[13]]],[-1,58,null,870335272692108,false,[[0,[0,3]]]]]],[0,null,false,null,131646557054595,[[0,59,null,1,false,false,false,891894169376380,false]],[[16,54,null,327930580854185,false,[[2,["correct",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[-1,41,null,202907159105342,false,[[4,15],[5,[0,1]],[0,[20,2,32,false,null]],[0,[20,2,33,false,null]]]],[15,46,null,145728902691754,false,[[0,[0,0]]]]]],[0,null,false,null,626804407280781,[[0,60,null,1,false,false,false,435087545862561,false]],[[16,54,null,217938364629081,false,[[2,["error-010-206498",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[-1,41,null,522820795913632,false,[[4,15],[5,[0,1]],[0,[20,2,32,false,null]],[0,[20,2,33,false,null]]]],[15,46,null,743250840849647,false,[[0,[0,1]]]]]],[0,null,false,null,138784311293898,[[4,51,null,1,false,false,false,318840334321068,false,[[4,5]]]],[[0,55,null,188346907636434,false]]],[0,null,false,null,144690028489488,[[4,51,null,1,false,false,false,961657910924384,false,[[4,6]]]],[[0,61,null,863067724909837,false]]],[0,null,false,null,339829265544415,[[0,62,null,1,false,false,false,425081282629100,false]],[[-1,27,null,357857564221621,false,[[11,"Paused"],[7,[0,1]]]]]],[0,null,false,null,619901953302901,[[0,63,null,1,false,false,false,453788771302771,false]],[[-1,27,null,986855891964228,false,[[11,"Paused"],[7,[0,0]]]]]],[0,null,false,null,678278685100726,[[-1,64,null,0,false,false,false,839154243379294,false]],[],[[0,null,false,null,203029406704081,[[-1,44,null,0,false,false,false,812877676162386,false,[[7,[20,0,65,false,null]],[8,4],[7,[0,0]]]]],[[-1,27,null,282958384255218,false,[[11,"timeLeft"],[7,[19,66,[[0,0],[5,[20,0,65,false,null],[20,0,67,false,null]]]]]]],[10,30,null,175097790282221,false,[[7,[19,28,[[23,"timeLeft"]]]]]]]]]],[0,null,false,null,978751838447749,[[-1,64,null,0,false,false,false,740586896137774,false]],[],[[0,null,false,null,539759871180422,[[-1,44,null,0,false,false,false,735943013123850,false,[[7,[20,0,67,false,null]],[8,4],[7,[20,0,65,false,null]]]],[-1,53,null,0,false,false,false,856670007560900,false,[[11,"isTimeUp"],[8,0],[7,[0,0]]]],[-1,68,null,0,false,false,false,955668488059869,false]],[[-1,27,null,302945892896402,false,[[11,"isTimeUp"],[7,[0,1]]]],[8,56,"DragDrop",118986934409651,false,[[3,0]]],[11,69,null,739058330936640,false],[8,70,"Fade",429052538282797,false],[-1,58,null,917300360080570,false,[[0,[1,1]]]],[7,70,"Fade",315915830094512,false],[8,26,null,585032189291227,false],[12,69,null,239984847558684,false],[0,71,null,474781657260693,false,[[7,[23,"answer"]]]]]]]],[0,null,false,null,365785861310817,[[9,72,null,2,false,false,false,466620429321609,false,[[1,[2,"currentAnswer"]]]]],[],[[0,null,false,null,780375794781622,[[-1,73,null,0,true,false,false,143001263185103,false,[[1,[2,"i"]],[0,[0,0]],[0,[5,[19,28,[[20,0,25,false,null]]],[0,1]]]]]],[],[[0,null,false,null,623354472074576,[[-1,74,null,0,false,false,false,929134158340487,false,[[4,7],[7,[21,7,false,null,0]],[8,0],[7,[19,38]]]]],[[-1,27,null,483299828391284,false,[[11,"answer"],[7,[10,[10,[23,"answer"],[21,7,true,null,1]],[2,"|"]]]]]]]]],[0,null,false,null,475666535596674,[],[[-1,27,null,374977936278745,false,[[11,"answer"],[7,[19,75,[[23,"answer"],[5,[19,76,[[23,"answer"]]],[0,1]]]]]]],[0,71,null,103117520878571,false,[[7,[23,"answer"]]]]]]]],[0,null,false,null,600608562107578,[[4,51,null,1,false,false,false,891500002256313,false,[[4,17]]]],[],[[0,null,false,null,426459896580949,[[21,77,null,0,false,false,false,811423894111416,false,[[8,0],[0,[20,17,33,false,null]]]]],[[20,78,"MoveTo",576994443738303,false,[[0,[21,20,false,null,0]],[0,[21,20,false,null,1]]]],[21,78,"MoveTo",664066818448917,false,[[0,[21,21,false,null,0]],[0,[21,21,false,null,1]]]]]],[0,null,false,null,813987173387856,[[21,77,null,0,false,false,false,360548133253360,false,[[8,0],[0,[21,21,false,null,1]]]]],[[20,79,"MoveTo",564863130284639,false,[[4,17]]],[21,79,"MoveTo",753250951346862,false,[[4,17]]]]]]],[0,null,false,null,398375489714286,[[4,51,null,1,false,false,false,723806263526938,false,[[4,21]]],[21,77,null,0,false,false,false,181942908228041,false,[[8,0],[0,[21,21,false,null,1]]]]],[],[[0,null,false,null,859972771487505,[[21,80,null,0,false,false,false,990148759371186,false,[[8,0],[0,[0,0]]]]],[[21,46,null,728229426682011,false,[[0,[0,1]]]],[16,81,null,436791612138112,false,[[3,0]]]]],[0,null,false,null,474877987440232,[[-1,47,null,0,false,false,false,904405232089990,false]],[[21,46,null,569169335937351,false,[[0,[0,0]]]],[16,81,null,898083323827850,false,[[3,1]]]]]]],[0,null,false,null,246743788520867,[[4,51,null,1,false,false,false,801931205987650,false,[[4,20]]],[20,77,null,0,false,false,false,551526414582339,false,[[8,0],[0,[21,20,false,null,1]]]]],[[0,55,null,135302385113891,false],[20,79,"MoveTo",959639910199972,false,[[4,17]]],[21,79,"MoveTo",258657396501857,false,[[4,17]]],[-1,58,null,387073202837793,false,[[0,[1,0.5]]]],[-1,14,null,357224634786112,false,[[5,[0,1]],[3,0]]],[-1,14,null,853002410411529,false,[[5,[0,2]],[3,1]]]]],[0,null,false,null,600080256108869,[[4,51,null,1,false,false,false,304672810310041,false,[[4,23]]],[-1,82,null,0,false,false,false,303482445048985,false,[[5,[0,2]]]]],[[0,61,null,684013340592645,false],[-1,14,null,519113282566716,false,[[5,[0,1]],[3,1]]],[-1,14,null,494131448394392,false,[[5,[0,2]],[3,0]]]]],[0,null,false,null,265453471250122,[[4,51,null,1,false,false,false,394936313563062,false,[[4,26]]]],[[16,54,null,625219449389702,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]]]]],["DrapDrop",[[1,"filledCount",0,0,false,false,528865922993012,false],[0,null,false,null,197106660861514,[[8,83,"DragDrop",1,false,false,false,528907557634308,false]],[[16,54,null,162558464641912,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]],[[0,null,false,null,266963171745346,[[8,84,null,0,false,false,false,673397366023432,false,[[10,3],[8,1],[7,[0,-1]]]],[7,84,null,0,false,false,false,577869128870380,false,[[10,0],[8,0],[7,[21,8,false,null,3]]]],[8,85,null,0,false,false,false,609479521709627,false,[[4,11]]]],[[7,31,null,445026196152632,false,[[10,1],[7,[2,"_"]]]],[8,86,null,670463517581139,false],[11,87,null,538995332098798,false]]],[0,null,false,null,816493828433722,[[-1,47,null,0,false,false,false,390659514117980,false]],[],[[0,null,false,null,487754364377713,[[8,85,null,0,false,false,false,443159185077976,false,[[4,11]]]],[[8,86,null,774809908055048,false],[11,87,null,501986465343455,false]]]]]]],[0,null,false,null,946639210805430,[[8,88,"DragDrop",1,false,false,false,155941787306139,false]],[[16,54,null,361413524752870,false,[[2,["immersivecontrol-button-click-sound-463065",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]],[[0,null,false,null,504792991445212,[[8,85,null,0,false,false,false,845450333794375,false,[[4,7]]],[7,89,null,0,false,true,false,204552588897544,false,[[10,2]]]],[],[[0,null,false,null,106550985509374,[[7,90,null,0,false,false,true,170480452496238,false,[[3,0],[0,[20,8,32,false,null]],[0,[20,8,33,false,null]]]],[7,84,null,0,false,false,false,938809230173413,false,[[10,1],[8,0],[7,[2,"_"]]]]],[[8,91,"MoveTo",350887864650832,false,[[0,[0,350]]]],[8,78,"MoveTo",122919247741976,false,[[0,[20,7,32,false,null]],[0,[20,7,33,false,null]]]],[7,31,null,568930528296173,false,[[10,1],[7,[21,8,true,null,0]]]]],[[0,null,false,null,101266177713061,[[8,84,null,0,false,false,false,148334850256636,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,31,null,762068200313175,false,[[10,3],[7,[21,7,false,null,0]]]],[-1,92,null,348122173801647,false,[[11,"filledCount"],[7,[0,1]]]]]],[0,null,false,null,296319278611324,[[-1,47,null,0,false,false,false,250133201929726,false]],[[8,31,null,116855994129968,false,[[10,3],[7,[21,7,false,null,0]]]]]]]],[0,null,false,null,180540551233675,[[-1,47,null,0,false,false,false,806523891610870,false],[8,84,null,0,false,false,false,831308228851461,false,[[10,3],[8,1],[7,[0,-1]]]]],[[8,91,"MoveTo",416883713281691,false,[[0,[0,1200]]]],[8,78,"MoveTo",572186182608955,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,370498434376498,false,[[10,3],[7,[0,-1]]]],[-1,92,null,250504698972287,false,[[11,"filledCount"],[7,[0,-1]]]]]],[0,null,false,null,664272208282422,[[-1,47,null,0,false,false,false,895425177786413,false],[8,84,null,0,false,false,false,246894625675163,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,91,"MoveTo",888826482377214,false,[[0,[0,1200]]]],[8,78,"MoveTo",393405307018971,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,503673017513230,false,[[10,3],[7,[0,-1]]]]]]]],[0,null,false,null,818745098688947,[[-1,47,null,0,false,false,false,929804756669469,false],[8,84,null,0,false,false,false,177859681995434,false,[[10,3],[8,1],[7,[0,-1]]]]],[[8,91,"MoveTo",449724002535088,false,[[0,[0,1200]]]],[8,78,"MoveTo",721292388859295,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,733212651291432,false,[[10,3],[7,[0,-1]]]],[-1,92,null,739300525987860,false,[[11,"filledCount"],[7,[0,-1]]]]]],[0,null,false,null,358120937494399,[[-1,47,null,0,false,false,false,416712700522674,false],[8,84,null,0,false,false,false,261187518957115,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,91,"MoveTo",431242330954619,false,[[0,[0,1200]]]],[8,78,"MoveTo",754072653542168,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,272960877861772,false,[[10,3],[7,[0,-1]]]]]]]],[0,null,false,null,580675938654997,[[8,93,"DragDrop",0,false,false,false,411147921527630,false]],[[8,34,null,610567804677855,false,[[0,[20,4,94,false,null]],[0,[20,4,95,false,null]]]]]],[0,null,false,null,622060364017684,[[-1,64,null,0,false,false,false,228576696549219,false]],[],[[0,null,false,null,108730370076990,[[-1,53,null,0,false,false,false,538413628199561,false,[[11,"filledCount"],[8,0],[7,[23,"end"]]]]],[[2,96,null,445242465744130,false,[[3,1]]]]],[0,null,false,null,218835501607731,[[-1,47,null,0,false,false,false,933470660702724,false]],[[2,96,null,797052197521566,false,[[3,0]]]]]]]]]],[["click.ogg",24620],["correct.ogg",60630],["error-010-206498.ogg",11425],["immersivecontrol-button-click-sound-463065.ogg",3830]],"media/",false,1200,1200,4,true,true,true,"1.0.0.0",true,false,3,0,25,false,true,1,true,"New project",0,[]]}
\ No newline at end of file
diff --git a/G102-sequence/icon-114.png b/G120-sequence/icon-114.png
similarity index 100%
rename from G102-sequence/icon-114.png
rename to G120-sequence/icon-114.png
diff --git a/G102-sequence/icon-128.png b/G120-sequence/icon-128.png
similarity index 100%
rename from G102-sequence/icon-128.png
rename to G120-sequence/icon-128.png
diff --git a/G102-sequence/icon-16.png b/G120-sequence/icon-16.png
similarity index 100%
rename from G102-sequence/icon-16.png
rename to G120-sequence/icon-16.png
diff --git a/G102-sequence/icon-256.png b/G120-sequence/icon-256.png
similarity index 100%
rename from G102-sequence/icon-256.png
rename to G120-sequence/icon-256.png
diff --git a/G102-sequence/icon-32.png b/G120-sequence/icon-32.png
similarity index 100%
rename from G102-sequence/icon-32.png
rename to G120-sequence/icon-32.png
diff --git a/New-project/images/5sosarahtakesoff-sheet0.png b/G120-sequence/images/5sosarahtakesoff-sheet0.png
similarity index 100%
rename from New-project/images/5sosarahtakesoff-sheet0.png
rename to G120-sequence/images/5sosarahtakesoff-sheet0.png
diff --git a/New-project/images/btn_check-sheet0.png b/G120-sequence/images/btn_check-sheet0.png
similarity index 100%
rename from New-project/images/btn_check-sheet0.png
rename to G120-sequence/images/btn_check-sheet0.png
diff --git a/New-project/images/btn_music-sheet0.png b/G120-sequence/images/btn_music-sheet0.png
similarity index 100%
rename from New-project/images/btn_music-sheet0.png
rename to G120-sequence/images/btn_music-sheet0.png
diff --git a/New-project/images/btn_music-sheet1.png b/G120-sequence/images/btn_music-sheet1.png
similarity index 100%
rename from New-project/images/btn_music-sheet1.png
rename to G120-sequence/images/btn_music-sheet1.png
diff --git a/New-project/images/btn_pause-sheet0.png b/G120-sequence/images/btn_pause-sheet0.png
similarity index 100%
rename from New-project/images/btn_pause-sheet0.png
rename to G120-sequence/images/btn_pause-sheet0.png
diff --git a/New-project/images/btn_setting-sheet0.png b/G120-sequence/images/btn_setting-sheet0.png
similarity index 100%
rename from New-project/images/btn_setting-sheet0.png
rename to G120-sequence/images/btn_setting-sheet0.png
diff --git a/New-project/images/checker_wrong_correct-sheet0.png b/G120-sequence/images/checker_wrong_correct-sheet0.png
similarity index 100%
rename from New-project/images/checker_wrong_correct-sheet0.png
rename to G120-sequence/images/checker_wrong_correct-sheet0.png
diff --git a/New-project/images/checker_wrong_correct-sheet1.png b/G120-sequence/images/checker_wrong_correct-sheet1.png
similarity index 100%
rename from New-project/images/checker_wrong_correct-sheet1.png
rename to G120-sequence/images/checker_wrong_correct-sheet1.png
diff --git a/New-project/images/layer-sheet0.png b/G120-sequence/images/layer-sheet0.png
similarity index 100%
rename from New-project/images/layer-sheet0.png
rename to G120-sequence/images/layer-sheet0.png
diff --git a/New-project/images/newwordpng-sheet0.png b/G120-sequence/images/newwordpng-sheet0.png
similarity index 100%
rename from New-project/images/newwordpng-sheet0.png
rename to G120-sequence/images/newwordpng-sheet0.png
diff --git a/New-project/images/panel-sheet0.png b/G120-sequence/images/panel-sheet0.png
similarity index 100%
rename from New-project/images/panel-sheet0.png
rename to G120-sequence/images/panel-sheet0.png
diff --git a/New-project/images/panel_pause-sheet0.png b/G120-sequence/images/panel_pause-sheet0.png
similarity index 100%
rename from New-project/images/panel_pause-sheet0.png
rename to G120-sequence/images/panel_pause-sheet0.png
diff --git a/New-project/images/pause-sheet0.png b/G120-sequence/images/pause-sheet0.png
similarity index 100%
rename from New-project/images/pause-sheet0.png
rename to G120-sequence/images/pause-sheet0.png
diff --git a/New-project/images/senaaikhoi-sheet0.png b/G120-sequence/images/senaaikhoi-sheet0.png
similarity index 100%
rename from New-project/images/senaaikhoi-sheet0.png
rename to G120-sequence/images/senaaikhoi-sheet0.png
diff --git a/New-project/images/slot-sheet0.png b/G120-sequence/images/slot-sheet0.png
similarity index 100%
rename from New-project/images/slot-sheet0.png
rename to G120-sequence/images/slot-sheet0.png
diff --git a/New-project/images/txt_question.png b/G120-sequence/images/txt_question.png
similarity index 100%
rename from New-project/images/txt_question.png
rename to G120-sequence/images/txt_question.png
diff --git a/New-project/images/txt_texttimer.png b/G120-sequence/images/txt_texttimer.png
similarity index 100%
rename from New-project/images/txt_texttimer.png
rename to G120-sequence/images/txt_texttimer.png
diff --git a/New-project/images/txt_worditem.png b/G120-sequence/images/txt_worditem.png
similarity index 100%
rename from New-project/images/txt_worditem.png
rename to G120-sequence/images/txt_worditem.png
diff --git a/New-project/images/wrong-sheet0.png b/G120-sequence/images/wrong-sheet0.png
similarity index 100%
rename from New-project/images/wrong-sheet0.png
rename to G120-sequence/images/wrong-sheet0.png
diff --git a/New-project/index.html b/G120-sequence/index.html
similarity index 100%
rename from New-project/index.html
rename to G120-sequence/index.html
diff --git a/G102-sequence/jquery-3.4.1.min.js b/G120-sequence/jquery-3.4.1.min.js
similarity index 100%
rename from G102-sequence/jquery-3.4.1.min.js
rename to G120-sequence/jquery-3.4.1.min.js
diff --git a/G102-sequence/loading-logo.png b/G120-sequence/loading-logo.png
similarity index 100%
rename from G102-sequence/loading-logo.png
rename to G120-sequence/loading-logo.png
diff --git a/New-project/media/click.ogg b/G120-sequence/media/click.ogg
similarity index 100%
rename from New-project/media/click.ogg
rename to G120-sequence/media/click.ogg
diff --git a/New-project/media/correct.ogg b/G120-sequence/media/correct.ogg
similarity index 100%
rename from New-project/media/correct.ogg
rename to G120-sequence/media/correct.ogg
diff --git a/New-project/media/error-010-206498.ogg b/G120-sequence/media/error-010-206498.ogg
similarity index 100%
rename from New-project/media/error-010-206498.ogg
rename to G120-sequence/media/error-010-206498.ogg
diff --git a/New-project/media/immersivecontrol-button-click-sound-463065.ogg b/G120-sequence/media/immersivecontrol-button-click-sound-463065.ogg
similarity index 100%
rename from New-project/media/immersivecontrol-button-click-sound-463065.ogg
rename to G120-sequence/media/immersivecontrol-button-click-sound-463065.ogg
diff --git a/New-project/offline.js b/G120-sequence/offline.js
similarity index 97%
rename from New-project/offline.js
rename to G120-sequence/offline.js
index 206a677..1834a3a 100644
--- a/New-project/offline.js
+++ b/G120-sequence/offline.js
@@ -1,5 +1,5 @@
{
- "version": 1769506337,
+ "version": 1769508966,
"fileList": [
"data.js",
"c2runtime.js",
diff --git a/G102-sequence/offlineClient.js b/G120-sequence/offlineClient.js
similarity index 100%
rename from G102-sequence/offlineClient.js
rename to G120-sequence/offlineClient.js
diff --git a/New-project/sena_sdk.js b/G120-sequence/sena_sdk.js
similarity index 100%
rename from New-project/sena_sdk.js
rename to G120-sequence/sena_sdk.js
diff --git a/G102-sequence/sw.js b/G120-sequence/sw.js
similarity index 100%
rename from G102-sequence/sw.js
rename to G120-sequence/sw.js
diff --git a/New-project/tdv_sdk.js b/G120-sequence/tdv_sdk.js
similarity index 100%
rename from New-project/tdv_sdk.js
rename to G120-sequence/tdv_sdk.js
diff --git a/New-project/c2runtime.js b/New-project/c2runtime.js
deleted file mode 100644
index ec1230b..0000000
--- a/New-project/c2runtime.js
+++ /dev/null
@@ -1,24430 +0,0 @@
-// Generated by Construct 2, the HTML5 game and app creator :: https://www.construct.net
-var cr = {};
-cr.plugins_ = {};
-cr.behaviors = {};
-if (typeof Object.getPrototypeOf !== "function")
-{
- if (typeof "test".__proto__ === "object")
- {
- Object.getPrototypeOf = function(object) {
- return object.__proto__;
- };
- }
- else
- {
- Object.getPrototypeOf = function(object) {
- return object.constructor.prototype;
- };
- }
-}
-(function(){
- cr.logexport = function (msg)
- {
- if (window.console && window.console.log)
- window.console.log(msg);
- };
- cr.logerror = function (msg)
- {
- if (window.console && window.console.error)
- window.console.error(msg);
- };
- cr.seal = function(x)
- {
- return x;
- };
- cr.freeze = function(x)
- {
- return x;
- };
- cr.is_undefined = function (x)
- {
- return typeof x === "undefined";
- };
- cr.is_number = function (x)
- {
- return typeof x === "number";
- };
- cr.is_string = function (x)
- {
- return typeof x === "string";
- };
- cr.isPOT = function (x)
- {
- return x > 0 && ((x - 1) & x) === 0;
- };
- cr.nextHighestPowerOfTwo = function(x) {
- --x;
- for (var i = 1; i < 32; i <<= 1) {
- x = x | x >> i;
- }
- return x + 1;
- }
- cr.abs = function (x)
- {
- return (x < 0 ? -x : x);
- };
- cr.max = function (a, b)
- {
- return (a > b ? a : b);
- };
- cr.min = function (a, b)
- {
- return (a < b ? a : b);
- };
- cr.PI = Math.PI;
- cr.round = function (x)
- {
- return (x + 0.5) | 0;
- };
- cr.floor = function (x)
- {
- if (x >= 0)
- return x | 0;
- else
- return (x | 0) - 1; // correctly round down when negative
- };
- cr.ceil = function (x)
- {
- var f = x | 0;
- return (f === x ? f : f + 1);
- };
- function Vector2(x, y)
- {
- this.x = x;
- this.y = y;
- cr.seal(this);
- };
- Vector2.prototype.offset = function (px, py)
- {
- this.x += px;
- this.y += py;
- return this;
- };
- Vector2.prototype.mul = function (px, py)
- {
- this.x *= px;
- this.y *= py;
- return this;
- };
- cr.vector2 = Vector2;
- cr.segments_intersect = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)
- {
- var max_ax, min_ax, max_ay, min_ay, max_bx, min_bx, max_by, min_by;
- if (a1x < a2x)
- {
- min_ax = a1x;
- max_ax = a2x;
- }
- else
- {
- min_ax = a2x;
- max_ax = a1x;
- }
- if (b1x < b2x)
- {
- min_bx = b1x;
- max_bx = b2x;
- }
- else
- {
- min_bx = b2x;
- max_bx = b1x;
- }
- if (max_ax < min_bx || min_ax > max_bx)
- return false;
- if (a1y < a2y)
- {
- min_ay = a1y;
- max_ay = a2y;
- }
- else
- {
- min_ay = a2y;
- max_ay = a1y;
- }
- if (b1y < b2y)
- {
- min_by = b1y;
- max_by = b2y;
- }
- else
- {
- min_by = b2y;
- max_by = b1y;
- }
- if (max_ay < min_by || min_ay > max_by)
- return false;
- var dpx = b1x - a1x + b2x - a2x;
- var dpy = b1y - a1y + b2y - a2y;
- var qax = a2x - a1x;
- var qay = a2y - a1y;
- var qbx = b2x - b1x;
- var qby = b2y - b1y;
- var d = cr.abs(qay * qbx - qby * qax);
- var la = qbx * dpy - qby * dpx;
- if (cr.abs(la) > d)
- return false;
- var lb = qax * dpy - qay * dpx;
- return cr.abs(lb) <= d;
- };
- function Rect(left, top, right, bottom)
- {
- this.set(left, top, right, bottom);
- cr.seal(this);
- };
- Rect.prototype.set = function (left, top, right, bottom)
- {
- this.left = left;
- this.top = top;
- this.right = right;
- this.bottom = bottom;
- };
- Rect.prototype.copy = function (r)
- {
- this.left = r.left;
- this.top = r.top;
- this.right = r.right;
- this.bottom = r.bottom;
- };
- Rect.prototype.width = function ()
- {
- return this.right - this.left;
- };
- Rect.prototype.height = function ()
- {
- return this.bottom - this.top;
- };
- Rect.prototype.offset = function (px, py)
- {
- this.left += px;
- this.top += py;
- this.right += px;
- this.bottom += py;
- return this;
- };
- Rect.prototype.normalize = function ()
- {
- var temp = 0;
- if (this.left > this.right)
- {
- temp = this.left;
- this.left = this.right;
- this.right = temp;
- }
- if (this.top > this.bottom)
- {
- temp = this.top;
- this.top = this.bottom;
- this.bottom = temp;
- }
- };
- Rect.prototype.intersects_rect = function (rc)
- {
- return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom);
- };
- Rect.prototype.intersects_rect_off = function (rc, ox, oy)
- {
- return !(rc.right + ox < this.left || rc.bottom + oy < this.top || rc.left + ox > this.right || rc.top + oy > this.bottom);
- };
- Rect.prototype.contains_pt = function (x, y)
- {
- return (x >= this.left && x <= this.right) && (y >= this.top && y <= this.bottom);
- };
- Rect.prototype.equals = function (r)
- {
- return this.left === r.left && this.top === r.top && this.right === r.right && this.bottom === r.bottom;
- };
- cr.rect = Rect;
- function Quad()
- {
- this.tlx = 0;
- this.tly = 0;
- this.trx = 0;
- this.try_ = 0; // is a keyword otherwise!
- this.brx = 0;
- this.bry = 0;
- this.blx = 0;
- this.bly = 0;
- cr.seal(this);
- };
- Quad.prototype.set_from_rect = function (rc)
- {
- this.tlx = rc.left;
- this.tly = rc.top;
- this.trx = rc.right;
- this.try_ = rc.top;
- this.brx = rc.right;
- this.bry = rc.bottom;
- this.blx = rc.left;
- this.bly = rc.bottom;
- };
- Quad.prototype.set_from_rotated_rect = function (rc, a)
- {
- if (a === 0)
- {
- this.set_from_rect(rc);
- }
- else
- {
- var sin_a = Math.sin(a);
- var cos_a = Math.cos(a);
- var left_sin_a = rc.left * sin_a;
- var top_sin_a = rc.top * sin_a;
- var right_sin_a = rc.right * sin_a;
- var bottom_sin_a = rc.bottom * sin_a;
- var left_cos_a = rc.left * cos_a;
- var top_cos_a = rc.top * cos_a;
- var right_cos_a = rc.right * cos_a;
- var bottom_cos_a = rc.bottom * cos_a;
- this.tlx = left_cos_a - top_sin_a;
- this.tly = top_cos_a + left_sin_a;
- this.trx = right_cos_a - top_sin_a;
- this.try_ = top_cos_a + right_sin_a;
- this.brx = right_cos_a - bottom_sin_a;
- this.bry = bottom_cos_a + right_sin_a;
- this.blx = left_cos_a - bottom_sin_a;
- this.bly = bottom_cos_a + left_sin_a;
- }
- };
- Quad.prototype.offset = function (px, py)
- {
- this.tlx += px;
- this.tly += py;
- this.trx += px;
- this.try_ += py;
- this.brx += px;
- this.bry += py;
- this.blx += px;
- this.bly += py;
- return this;
- };
- var minresult = 0;
- var maxresult = 0;
- function minmax4(a, b, c, d)
- {
- if (a < b)
- {
- if (c < d)
- {
- if (a < c)
- minresult = a;
- else
- minresult = c;
- if (b > d)
- maxresult = b;
- else
- maxresult = d;
- }
- else
- {
- if (a < d)
- minresult = a;
- else
- minresult = d;
- if (b > c)
- maxresult = b;
- else
- maxresult = c;
- }
- }
- else
- {
- if (c < d)
- {
- if (b < c)
- minresult = b;
- else
- minresult = c;
- if (a > d)
- maxresult = a;
- else
- maxresult = d;
- }
- else
- {
- if (b < d)
- minresult = b;
- else
- minresult = d;
- if (a > c)
- maxresult = a;
- else
- maxresult = c;
- }
- }
- };
- Quad.prototype.bounding_box = function (rc)
- {
- minmax4(this.tlx, this.trx, this.brx, this.blx);
- rc.left = minresult;
- rc.right = maxresult;
- minmax4(this.tly, this.try_, this.bry, this.bly);
- rc.top = minresult;
- rc.bottom = maxresult;
- };
- Quad.prototype.contains_pt = function (x, y)
- {
- var tlx = this.tlx;
- var tly = this.tly;
- var v0x = this.trx - tlx;
- var v0y = this.try_ - tly;
- var v1x = this.brx - tlx;
- var v1y = this.bry - tly;
- var v2x = x - tlx;
- var v2y = y - tly;
- var dot00 = v0x * v0x + v0y * v0y
- var dot01 = v0x * v1x + v0y * v1y
- var dot02 = v0x * v2x + v0y * v2y
- var dot11 = v1x * v1x + v1y * v1y
- var dot12 = v1x * v2x + v1y * v2y
- var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
- var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
- if ((u >= 0.0) && (v > 0.0) && (u + v < 1))
- return true;
- v0x = this.blx - tlx;
- v0y = this.bly - tly;
- var dot00 = v0x * v0x + v0y * v0y
- var dot01 = v0x * v1x + v0y * v1y
- var dot02 = v0x * v2x + v0y * v2y
- invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
- u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- v = (dot00 * dot12 - dot01 * dot02) * invDenom;
- return (u >= 0.0) && (v > 0.0) && (u + v < 1);
- };
- Quad.prototype.at = function (i, xory)
- {
- if (xory)
- {
- switch (i)
- {
- case 0: return this.tlx;
- case 1: return this.trx;
- case 2: return this.brx;
- case 3: return this.blx;
- case 4: return this.tlx;
- default: return this.tlx;
- }
- }
- else
- {
- switch (i)
- {
- case 0: return this.tly;
- case 1: return this.try_;
- case 2: return this.bry;
- case 3: return this.bly;
- case 4: return this.tly;
- default: return this.tly;
- }
- }
- };
- Quad.prototype.midX = function ()
- {
- return (this.tlx + this.trx + this.brx + this.blx) / 4;
- };
- Quad.prototype.midY = function ()
- {
- return (this.tly + this.try_ + this.bry + this.bly) / 4;
- };
- Quad.prototype.intersects_segment = function (x1, y1, x2, y2)
- {
- if (this.contains_pt(x1, y1) || this.contains_pt(x2, y2))
- return true;
- var a1x, a1y, a2x, a2y;
- var i;
- for (i = 0; i < 4; i++)
- {
- a1x = this.at(i, true);
- a1y = this.at(i, false);
- a2x = this.at(i + 1, true);
- a2y = this.at(i + 1, false);
- if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
- return true;
- }
- return false;
- };
- Quad.prototype.intersects_quad = function (rhs)
- {
- var midx = rhs.midX();
- var midy = rhs.midY();
- if (this.contains_pt(midx, midy))
- return true;
- midx = this.midX();
- midy = this.midY();
- if (rhs.contains_pt(midx, midy))
- return true;
- var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
- var i, j;
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 4; j++)
- {
- a1x = this.at(i, true);
- a1y = this.at(i, false);
- a2x = this.at(i + 1, true);
- a2y = this.at(i + 1, false);
- b1x = rhs.at(j, true);
- b1y = rhs.at(j, false);
- b2x = rhs.at(j + 1, true);
- b2y = rhs.at(j + 1, false);
- if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
- return true;
- }
- }
- return false;
- };
- cr.quad = Quad;
- cr.RGB = function (red, green, blue)
- {
- return Math.max(Math.min(red, 255), 0)
- | (Math.max(Math.min(green, 255), 0) << 8)
- | (Math.max(Math.min(blue, 255), 0) << 16);
- };
- cr.GetRValue = function (rgb)
- {
- return rgb & 0xFF;
- };
- cr.GetGValue = function (rgb)
- {
- return (rgb & 0xFF00) >> 8;
- };
- cr.GetBValue = function (rgb)
- {
- return (rgb & 0xFF0000) >> 16;
- };
- cr.shallowCopy = function (a, b, allowOverwrite)
- {
- var attr;
- for (attr in b)
- {
- if (b.hasOwnProperty(attr))
- {
-;
- a[attr] = b[attr];
- }
- }
- return a;
- };
- cr.arrayRemove = function (arr, index)
- {
- var i, len;
- index = cr.floor(index);
- if (index < 0 || index >= arr.length)
- return; // index out of bounds
- for (i = index, len = arr.length - 1; i < len; i++)
- arr[i] = arr[i + 1];
- cr.truncateArray(arr, len);
- };
- cr.truncateArray = function (arr, index)
- {
- arr.length = index;
- };
- cr.clearArray = function (arr)
- {
- cr.truncateArray(arr, 0);
- };
- cr.shallowAssignArray = function (dest, src)
- {
- cr.clearArray(dest);
- var i, len;
- for (i = 0, len = src.length; i < len; ++i)
- dest[i] = src[i];
- };
- cr.appendArray = function (a, b)
- {
- a.push.apply(a, b);
- };
- cr.fastIndexOf = function (arr, item)
- {
- var i, len;
- for (i = 0, len = arr.length; i < len; ++i)
- {
- if (arr[i] === item)
- return i;
- }
- return -1;
- };
- cr.arrayFindRemove = function (arr, item)
- {
- var index = cr.fastIndexOf(arr, item);
- if (index !== -1)
- cr.arrayRemove(arr, index);
- };
- cr.clamp = function(x, a, b)
- {
- if (x < a)
- return a;
- else if (x > b)
- return b;
- else
- return x;
- };
- cr.to_radians = function(x)
- {
- return x / (180.0 / cr.PI);
- };
- cr.to_degrees = function(x)
- {
- return x * (180.0 / cr.PI);
- };
- cr.clamp_angle_degrees = function (a)
- {
- a %= 360; // now in (-360, 360) range
- if (a < 0)
- a += 360; // now in [0, 360) range
- return a;
- };
- cr.clamp_angle = function (a)
- {
- a %= 2 * cr.PI; // now in (-2pi, 2pi) range
- if (a < 0)
- a += 2 * cr.PI; // now in [0, 2pi) range
- return a;
- };
- cr.to_clamped_degrees = function (x)
- {
- return cr.clamp_angle_degrees(cr.to_degrees(x));
- };
- cr.to_clamped_radians = function (x)
- {
- return cr.clamp_angle(cr.to_radians(x));
- };
- cr.angleTo = function(x1, y1, x2, y2)
- {
- var dx = x2 - x1;
- var dy = y2 - y1;
- return Math.atan2(dy, dx);
- };
- cr.angleDiff = function (a1, a2)
- {
- if (a1 === a2)
- return 0;
- var s1 = Math.sin(a1);
- var c1 = Math.cos(a1);
- var s2 = Math.sin(a2);
- var c2 = Math.cos(a2);
- var n = s1 * s2 + c1 * c2;
- if (n >= 1)
- return 0;
- if (n <= -1)
- return cr.PI;
- return Math.acos(n);
- };
- cr.angleRotate = function (start, end, step)
- {
- var ss = Math.sin(start);
- var cs = Math.cos(start);
- var se = Math.sin(end);
- var ce = Math.cos(end);
- if (Math.acos(ss * se + cs * ce) > step)
- {
- if (cs * se - ss * ce > 0)
- return cr.clamp_angle(start + step);
- else
- return cr.clamp_angle(start - step);
- }
- else
- return cr.clamp_angle(end);
- };
- cr.angleClockwise = function (a1, a2)
- {
- var s1 = Math.sin(a1);
- var c1 = Math.cos(a1);
- var s2 = Math.sin(a2);
- var c2 = Math.cos(a2);
- return c1 * s2 - s1 * c2 <= 0;
- };
- cr.rotatePtAround = function (px, py, a, ox, oy, getx)
- {
- if (a === 0)
- return getx ? px : py;
- var sin_a = Math.sin(a);
- var cos_a = Math.cos(a);
- px -= ox;
- py -= oy;
- var left_sin_a = px * sin_a;
- var top_sin_a = py * sin_a;
- var left_cos_a = px * cos_a;
- var top_cos_a = py * cos_a;
- px = left_cos_a - top_sin_a;
- py = top_cos_a + left_sin_a;
- px += ox;
- py += oy;
- return getx ? px : py;
- }
- cr.distanceTo = function(x1, y1, x2, y2)
- {
- var dx = x2 - x1;
- var dy = y2 - y1;
- return Math.sqrt(dx*dx + dy*dy);
- };
- cr.xor = function (x, y)
- {
- return !x !== !y;
- };
- cr.lerp = function (a, b, x)
- {
- return a + (b - a) * x;
- };
- cr.unlerp = function (a, b, c)
- {
- if (a === b)
- return 0; // avoid divide by 0
- return (c - a) / (b - a);
- };
- cr.anglelerp = function (a, b, x)
- {
- var diff = cr.angleDiff(a, b);
- if (cr.angleClockwise(b, a))
- {
- return a + diff * x;
- }
- else
- {
- return a - diff * x;
- }
- };
- cr.qarp = function (a, b, c, x)
- {
- return cr.lerp(cr.lerp(a, b, x), cr.lerp(b, c, x), x);
- };
- cr.cubic = function (a, b, c, d, x)
- {
- return cr.lerp(cr.qarp(a, b, c, x), cr.qarp(b, c, d, x), x);
- };
- cr.cosp = function (a, b, x)
- {
- return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2;
- };
- cr.hasAnyOwnProperty = function (o)
- {
- var p;
- for (p in o)
- {
- if (o.hasOwnProperty(p))
- return true;
- }
- return false;
- };
- cr.wipe = function (obj)
- {
- var p;
- for (p in obj)
- {
- if (obj.hasOwnProperty(p))
- delete obj[p];
- }
- };
- var startup_time = +(new Date());
- cr.performance_now = function()
- {
- if (typeof window["performance"] !== "undefined")
- {
- var winperf = window["performance"];
- if (typeof winperf.now !== "undefined")
- return winperf.now();
- else if (typeof winperf["webkitNow"] !== "undefined")
- return winperf["webkitNow"]();
- else if (typeof winperf["mozNow"] !== "undefined")
- return winperf["mozNow"]();
- else if (typeof winperf["msNow"] !== "undefined")
- return winperf["msNow"]();
- }
- return Date.now() - startup_time;
- };
- var isChrome = false;
- var isSafari = false;
- var isiOS = false;
- var isEjecta = false;
- if (typeof window !== "undefined") // not c2 editor
- {
- isChrome = /chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent);
- isSafari = !isChrome && /safari/i.test(navigator.userAgent);
- isiOS = /(iphone|ipod|ipad)/i.test(navigator.userAgent);
- isEjecta = window["c2ejecta"];
- }
- var supports_set = ((!isSafari && !isEjecta && !isiOS) && (typeof Set !== "undefined" && typeof Set.prototype["forEach"] !== "undefined"));
- function ObjectSet_()
- {
- this.s = null;
- this.items = null; // lazy allocated (hopefully results in better GC performance)
- this.item_count = 0;
- if (supports_set)
- {
- this.s = new Set();
- }
- this.values_cache = [];
- this.cache_valid = true;
- cr.seal(this);
- };
- ObjectSet_.prototype.contains = function (x)
- {
- if (this.isEmpty())
- return false;
- if (supports_set)
- return this.s["has"](x);
- else
- return (this.items && this.items.hasOwnProperty(x));
- };
- ObjectSet_.prototype.add = function (x)
- {
- if (supports_set)
- {
- if (!this.s["has"](x))
- {
- this.s["add"](x);
- this.cache_valid = false;
- }
- }
- else
- {
- var str = x.toString();
- var items = this.items;
- if (!items)
- {
- this.items = {};
- this.items[str] = x;
- this.item_count = 1;
- this.cache_valid = false;
- }
- else if (!items.hasOwnProperty(str))
- {
- items[str] = x;
- this.item_count++;
- this.cache_valid = false;
- }
- }
- };
- ObjectSet_.prototype.remove = function (x)
- {
- if (this.isEmpty())
- return;
- if (supports_set)
- {
- if (this.s["has"](x))
- {
- this.s["delete"](x);
- this.cache_valid = false;
- }
- }
- else if (this.items)
- {
- var str = x.toString();
- var items = this.items;
- if (items.hasOwnProperty(str))
- {
- delete items[str];
- this.item_count--;
- this.cache_valid = false;
- }
- }
- };
- ObjectSet_.prototype.clear = function (/*wipe_*/)
- {
- if (this.isEmpty())
- return;
- if (supports_set)
- {
- this.s["clear"](); // best!
- }
- else
- {
- this.items = null; // creates garbage; will lazy allocate on next add()
- this.item_count = 0;
- }
- cr.clearArray(this.values_cache);
- this.cache_valid = true;
- };
- ObjectSet_.prototype.isEmpty = function ()
- {
- return this.count() === 0;
- };
- ObjectSet_.prototype.count = function ()
- {
- if (supports_set)
- return this.s["size"];
- else
- return this.item_count;
- };
- var current_arr = null;
- var current_index = 0;
- function set_append_to_arr(x)
- {
- current_arr[current_index++] = x;
- };
- ObjectSet_.prototype.update_cache = function ()
- {
- if (this.cache_valid)
- return;
- if (supports_set)
- {
- cr.clearArray(this.values_cache);
- current_arr = this.values_cache;
- current_index = 0;
- this.s["forEach"](set_append_to_arr);
-;
- current_arr = null;
- current_index = 0;
- }
- else
- {
- var values_cache = this.values_cache;
- cr.clearArray(values_cache);
- var p, n = 0, items = this.items;
- if (items)
- {
- for (p in items)
- {
- if (items.hasOwnProperty(p))
- values_cache[n++] = items[p];
- }
- }
-;
- }
- this.cache_valid = true;
- };
- ObjectSet_.prototype.valuesRef = function ()
- {
- this.update_cache();
- return this.values_cache;
- };
- cr.ObjectSet = ObjectSet_;
- var tmpSet = new cr.ObjectSet();
- cr.removeArrayDuplicates = function (arr)
- {
- var i, len;
- for (i = 0, len = arr.length; i < len; ++i)
- {
- tmpSet.add(arr[i]);
- }
- cr.shallowAssignArray(arr, tmpSet.valuesRef());
- tmpSet.clear();
- };
- cr.arrayRemoveAllFromObjectSet = function (arr, remset)
- {
- if (supports_set)
- cr.arrayRemoveAll_set(arr, remset.s);
- else
- cr.arrayRemoveAll_arr(arr, remset.valuesRef());
- };
- cr.arrayRemoveAll_set = function (arr, s)
- {
- var i, j, len, item;
- for (i = 0, j = 0, len = arr.length; i < len; ++i)
- {
- item = arr[i];
- if (!s["has"](item)) // not an item to remove
- arr[j++] = item; // keep it
- }
- cr.truncateArray(arr, j);
- };
- cr.arrayRemoveAll_arr = function (arr, rem)
- {
- var i, j, len, item;
- for (i = 0, j = 0, len = arr.length; i < len; ++i)
- {
- item = arr[i];
- if (cr.fastIndexOf(rem, item) === -1) // not an item to remove
- arr[j++] = item; // keep it
- }
- cr.truncateArray(arr, j);
- };
- function KahanAdder_()
- {
- this.c = 0;
- this.y = 0;
- this.t = 0;
- this.sum = 0;
- cr.seal(this);
- };
- KahanAdder_.prototype.add = function (v)
- {
- this.y = v - this.c;
- this.t = this.sum + this.y;
- this.c = (this.t - this.sum) - this.y;
- this.sum = this.t;
- };
- KahanAdder_.prototype.reset = function ()
- {
- this.c = 0;
- this.y = 0;
- this.t = 0;
- this.sum = 0;
- };
- cr.KahanAdder = KahanAdder_;
- cr.regexp_escape = function(text)
- {
- return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
- };
- function CollisionPoly_(pts_array_)
- {
- this.pts_cache = [];
- this.bboxLeft = 0;
- this.bboxTop = 0;
- this.bboxRight = 0;
- this.bboxBottom = 0;
- this.convexpolys = null; // for physics behavior to cache separated polys
- this.set_pts(pts_array_);
- cr.seal(this);
- };
- CollisionPoly_.prototype.set_pts = function(pts_array_)
- {
- this.pts_array = pts_array_;
- this.pts_count = pts_array_.length / 2; // x, y, x, y... in array
- this.pts_cache.length = pts_array_.length;
- this.cache_width = -1;
- this.cache_height = -1;
- this.cache_angle = 0;
- };
- CollisionPoly_.prototype.is_empty = function()
- {
- return !this.pts_array.length;
- };
- CollisionPoly_.prototype.update_bbox = function ()
- {
- var myptscache = this.pts_cache;
- var bboxLeft_ = myptscache[0];
- var bboxRight_ = bboxLeft_;
- var bboxTop_ = myptscache[1];
- var bboxBottom_ = bboxTop_;
- var x, y, i = 1, i2, len = this.pts_count;
- for ( ; i < len; ++i)
- {
- i2 = i*2;
- x = myptscache[i2];
- y = myptscache[i2+1];
- if (x < bboxLeft_)
- bboxLeft_ = x;
- if (x > bboxRight_)
- bboxRight_ = x;
- if (y < bboxTop_)
- bboxTop_ = y;
- if (y > bboxBottom_)
- bboxBottom_ = y;
- }
- this.bboxLeft = bboxLeft_;
- this.bboxRight = bboxRight_;
- this.bboxTop = bboxTop_;
- this.bboxBottom = bboxBottom_;
- };
- CollisionPoly_.prototype.set_from_rect = function(rc, offx, offy)
- {
- this.pts_cache.length = 8;
- this.pts_count = 4;
- var myptscache = this.pts_cache;
- myptscache[0] = rc.left - offx;
- myptscache[1] = rc.top - offy;
- myptscache[2] = rc.right - offx;
- myptscache[3] = rc.top - offy;
- myptscache[4] = rc.right - offx;
- myptscache[5] = rc.bottom - offy;
- myptscache[6] = rc.left - offx;
- myptscache[7] = rc.bottom - offy;
- this.cache_width = rc.right - rc.left;
- this.cache_height = rc.bottom - rc.top;
- this.update_bbox();
- };
- CollisionPoly_.prototype.set_from_quad = function(q, offx, offy, w, h)
- {
- this.pts_cache.length = 8;
- this.pts_count = 4;
- var myptscache = this.pts_cache;
- myptscache[0] = q.tlx - offx;
- myptscache[1] = q.tly - offy;
- myptscache[2] = q.trx - offx;
- myptscache[3] = q.try_ - offy;
- myptscache[4] = q.brx - offx;
- myptscache[5] = q.bry - offy;
- myptscache[6] = q.blx - offx;
- myptscache[7] = q.bly - offy;
- this.cache_width = w;
- this.cache_height = h;
- this.update_bbox();
- };
- CollisionPoly_.prototype.set_from_poly = function (r)
- {
- this.pts_count = r.pts_count;
- cr.shallowAssignArray(this.pts_cache, r.pts_cache);
- this.bboxLeft = r.bboxLeft;
- this.bboxTop = r.bboxTop;
- this.bboxRight = r.bboxRight;
- this.bboxBottom = r.bboxBottom;
- };
- CollisionPoly_.prototype.cache_poly = function(w, h, a)
- {
- if (this.cache_width === w && this.cache_height === h && this.cache_angle === a)
- return; // cache up-to-date
- this.cache_width = w;
- this.cache_height = h;
- this.cache_angle = a;
- var i, i2, i21, len, x, y;
- var sina = 0;
- var cosa = 1;
- var myptsarray = this.pts_array;
- var myptscache = this.pts_cache;
- if (a !== 0)
- {
- sina = Math.sin(a);
- cosa = Math.cos(a);
- }
- for (i = 0, len = this.pts_count; i < len; i++)
- {
- i2 = i*2;
- i21 = i2+1;
- x = myptsarray[i2] * w;
- y = myptsarray[i21] * h;
- myptscache[i2] = (x * cosa) - (y * sina);
- myptscache[i21] = (y * cosa) + (x * sina);
- }
- this.update_bbox();
- };
- CollisionPoly_.prototype.contains_pt = function (a2x, a2y)
- {
- var myptscache = this.pts_cache;
- if (a2x === myptscache[0] && a2y === myptscache[1])
- return true;
- var i, i2, imod, len = this.pts_count;
- var a1x = this.bboxLeft - 110;
- var a1y = this.bboxTop - 101;
- var a3x = this.bboxRight + 131
- var a3y = this.bboxBottom + 120;
- var b1x, b1y, b2x, b2y;
- var count1 = 0, count2 = 0;
- for (i = 0; i < len; i++)
- {
- i2 = i*2;
- imod = ((i+1)%len)*2;
- b1x = myptscache[i2];
- b1y = myptscache[i2+1];
- b2x = myptscache[imod];
- b2y = myptscache[imod+1];
- if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
- count1++;
- if (cr.segments_intersect(a3x, a3y, a2x, a2y, b1x, b1y, b2x, b2y))
- count2++;
- }
- return (count1 % 2 === 1) || (count2 % 2 === 1);
- };
- CollisionPoly_.prototype.intersects_poly = function (rhs, offx, offy)
- {
- var rhspts = rhs.pts_cache;
- var mypts = this.pts_cache;
- if (this.contains_pt(rhspts[0] + offx, rhspts[1] + offy))
- return true;
- if (rhs.contains_pt(mypts[0] - offx, mypts[1] - offy))
- return true;
- var i, i2, imod, leni, j, j2, jmod, lenj;
- var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
- for (i = 0, leni = this.pts_count; i < leni; i++)
- {
- i2 = i*2;
- imod = ((i+1)%leni)*2;
- a1x = mypts[i2];
- a1y = mypts[i2+1];
- a2x = mypts[imod];
- a2y = mypts[imod+1];
- for (j = 0, lenj = rhs.pts_count; j < lenj; j++)
- {
- j2 = j*2;
- jmod = ((j+1)%lenj)*2;
- b1x = rhspts[j2] + offx;
- b1y = rhspts[j2+1] + offy;
- b2x = rhspts[jmod] + offx;
- b2y = rhspts[jmod+1] + offy;
- if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
- return true;
- }
- }
- return false;
- };
- CollisionPoly_.prototype.intersects_segment = function (offx, offy, x1, y1, x2, y2)
- {
- var mypts = this.pts_cache;
- if (this.contains_pt(x1 - offx, y1 - offy))
- return true;
- var i, leni, i2, imod;
- var a1x, a1y, a2x, a2y;
- for (i = 0, leni = this.pts_count; i < leni; i++)
- {
- i2 = i*2;
- imod = ((i+1)%leni)*2;
- a1x = mypts[i2] + offx;
- a1y = mypts[i2+1] + offy;
- a2x = mypts[imod] + offx;
- a2y = mypts[imod+1] + offy;
- if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
- return true;
- }
- return false;
- };
- CollisionPoly_.prototype.mirror = function (px)
- {
- var i, leni, i2;
- for (i = 0, leni = this.pts_count; i < leni; ++i)
- {
- i2 = i*2;
- this.pts_cache[i2] = px * 2 - this.pts_cache[i2];
- }
- };
- CollisionPoly_.prototype.flip = function (py)
- {
- var i, leni, i21;
- for (i = 0, leni = this.pts_count; i < leni; ++i)
- {
- i21 = i*2+1;
- this.pts_cache[i21] = py * 2 - this.pts_cache[i21];
- }
- };
- CollisionPoly_.prototype.diag = function ()
- {
- var i, leni, i2, i21, temp;
- for (i = 0, leni = this.pts_count; i < leni; ++i)
- {
- i2 = i*2;
- i21 = i2+1;
- temp = this.pts_cache[i2];
- this.pts_cache[i2] = this.pts_cache[i21];
- this.pts_cache[i21] = temp;
- }
- };
- cr.CollisionPoly = CollisionPoly_;
- function SparseGrid_(cellwidth_, cellheight_)
- {
- this.cellwidth = cellwidth_;
- this.cellheight = cellheight_;
- this.cells = {};
- };
- SparseGrid_.prototype.totalCellCount = 0;
- SparseGrid_.prototype.getCell = function (x_, y_, create_if_missing)
- {
- var ret;
- var col = this.cells[x_];
- if (!col)
- {
- if (create_if_missing)
- {
- ret = allocGridCell(this, x_, y_);
- this.cells[x_] = {};
- this.cells[x_][y_] = ret;
- return ret;
- }
- else
- return null;
- }
- ret = col[y_];
- if (ret)
- return ret;
- else if (create_if_missing)
- {
- ret = allocGridCell(this, x_, y_);
- this.cells[x_][y_] = ret;
- return ret;
- }
- else
- return null;
- };
- SparseGrid_.prototype.XToCell = function (x_)
- {
- return cr.floor(x_ / this.cellwidth);
- };
- SparseGrid_.prototype.YToCell = function (y_)
- {
- return cr.floor(y_ / this.cellheight);
- };
- SparseGrid_.prototype.update = function (inst, oldrange, newrange)
- {
- var x, lenx, y, leny, cell;
- if (oldrange)
- {
- for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
- {
- for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
- {
- if (newrange && newrange.contains_pt(x, y))
- continue; // is still in this cell
- cell = this.getCell(x, y, false); // don't create if missing
- if (!cell)
- continue; // cell does not exist yet
- cell.remove(inst);
- if (cell.isEmpty())
- {
- freeGridCell(cell);
- this.cells[x][y] = null;
- }
- }
- }
- }
- if (newrange)
- {
- for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
- {
- for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
- {
- if (oldrange && oldrange.contains_pt(x, y))
- continue; // is still in this cell
- this.getCell(x, y, true).insert(inst);
- }
- }
- }
- };
- SparseGrid_.prototype.queryRange = function (rc, result)
- {
- var x, lenx, ystart, y, leny, cell;
- x = this.XToCell(rc.left);
- ystart = this.YToCell(rc.top);
- lenx = this.XToCell(rc.right);
- leny = this.YToCell(rc.bottom);
- for ( ; x <= lenx; ++x)
- {
- for (y = ystart; y <= leny; ++y)
- {
- cell = this.getCell(x, y, false);
- if (!cell)
- continue;
- cell.dump(result);
- }
- }
- };
- cr.SparseGrid = SparseGrid_;
- function RenderGrid_(cellwidth_, cellheight_)
- {
- this.cellwidth = cellwidth_;
- this.cellheight = cellheight_;
- this.cells = {};
- };
- RenderGrid_.prototype.totalCellCount = 0;
- RenderGrid_.prototype.getCell = function (x_, y_, create_if_missing)
- {
- var ret;
- var col = this.cells[x_];
- if (!col)
- {
- if (create_if_missing)
- {
- ret = allocRenderCell(this, x_, y_);
- this.cells[x_] = {};
- this.cells[x_][y_] = ret;
- return ret;
- }
- else
- return null;
- }
- ret = col[y_];
- if (ret)
- return ret;
- else if (create_if_missing)
- {
- ret = allocRenderCell(this, x_, y_);
- this.cells[x_][y_] = ret;
- return ret;
- }
- else
- return null;
- };
- RenderGrid_.prototype.XToCell = function (x_)
- {
- return cr.floor(x_ / this.cellwidth);
- };
- RenderGrid_.prototype.YToCell = function (y_)
- {
- return cr.floor(y_ / this.cellheight);
- };
- RenderGrid_.prototype.update = function (inst, oldrange, newrange)
- {
- var x, lenx, y, leny, cell;
- if (oldrange)
- {
- for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
- {
- for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
- {
- if (newrange && newrange.contains_pt(x, y))
- continue; // is still in this cell
- cell = this.getCell(x, y, false); // don't create if missing
- if (!cell)
- continue; // cell does not exist yet
- cell.remove(inst);
- if (cell.isEmpty())
- {
- freeRenderCell(cell);
- this.cells[x][y] = null;
- }
- }
- }
- }
- if (newrange)
- {
- for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
- {
- for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
- {
- if (oldrange && oldrange.contains_pt(x, y))
- continue; // is still in this cell
- this.getCell(x, y, true).insert(inst);
- }
- }
- }
- };
- RenderGrid_.prototype.queryRange = function (left, top, right, bottom, result)
- {
- var x, lenx, ystart, y, leny, cell;
- x = this.XToCell(left);
- ystart = this.YToCell(top);
- lenx = this.XToCell(right);
- leny = this.YToCell(bottom);
- for ( ; x <= lenx; ++x)
- {
- for (y = ystart; y <= leny; ++y)
- {
- cell = this.getCell(x, y, false);
- if (!cell)
- continue;
- cell.dump(result);
- }
- }
- };
- RenderGrid_.prototype.markRangeChanged = function (rc)
- {
- var x, lenx, ystart, y, leny, cell;
- x = rc.left;
- ystart = rc.top;
- lenx = rc.right;
- leny = rc.bottom;
- for ( ; x <= lenx; ++x)
- {
- for (y = ystart; y <= leny; ++y)
- {
- cell = this.getCell(x, y, false);
- if (!cell)
- continue;
- cell.is_sorted = false;
- }
- }
- };
- cr.RenderGrid = RenderGrid_;
- var gridcellcache = [];
- function allocGridCell(grid_, x_, y_)
- {
- var ret;
- SparseGrid_.prototype.totalCellCount++;
- if (gridcellcache.length)
- {
- ret = gridcellcache.pop();
- ret.grid = grid_;
- ret.x = x_;
- ret.y = y_;
- return ret;
- }
- else
- return new cr.GridCell(grid_, x_, y_);
- };
- function freeGridCell(c)
- {
- SparseGrid_.prototype.totalCellCount--;
- c.objects.clear();
- if (gridcellcache.length < 1000)
- gridcellcache.push(c);
- };
- function GridCell_(grid_, x_, y_)
- {
- this.grid = grid_;
- this.x = x_;
- this.y = y_;
- this.objects = new cr.ObjectSet();
- };
- GridCell_.prototype.isEmpty = function ()
- {
- return this.objects.isEmpty();
- };
- GridCell_.prototype.insert = function (inst)
- {
- this.objects.add(inst);
- };
- GridCell_.prototype.remove = function (inst)
- {
- this.objects.remove(inst);
- };
- GridCell_.prototype.dump = function (result)
- {
- cr.appendArray(result, this.objects.valuesRef());
- };
- cr.GridCell = GridCell_;
- var rendercellcache = [];
- function allocRenderCell(grid_, x_, y_)
- {
- var ret;
- RenderGrid_.prototype.totalCellCount++;
- if (rendercellcache.length)
- {
- ret = rendercellcache.pop();
- ret.grid = grid_;
- ret.x = x_;
- ret.y = y_;
- return ret;
- }
- else
- return new cr.RenderCell(grid_, x_, y_);
- };
- function freeRenderCell(c)
- {
- RenderGrid_.prototype.totalCellCount--;
- c.reset();
- if (rendercellcache.length < 1000)
- rendercellcache.push(c);
- };
- function RenderCell_(grid_, x_, y_)
- {
- this.grid = grid_;
- this.x = x_;
- this.y = y_;
- this.objects = []; // array which needs to be sorted by Z order
- this.is_sorted = true; // whether array is in correct sort order or not
- this.pending_removal = new cr.ObjectSet();
- this.any_pending_removal = false;
- };
- RenderCell_.prototype.isEmpty = function ()
- {
- if (!this.objects.length)
- {
-;
-;
- return true;
- }
- if (this.objects.length > this.pending_removal.count())
- return false;
-;
- this.flush_pending(); // takes fast path and just resets state
- return true;
- };
- RenderCell_.prototype.insert = function (inst)
- {
- if (this.pending_removal.contains(inst))
- {
- this.pending_removal.remove(inst);
- if (this.pending_removal.isEmpty())
- this.any_pending_removal = false;
- return;
- }
- if (this.objects.length)
- {
- var top = this.objects[this.objects.length - 1];
- if (top.get_zindex() > inst.get_zindex())
- this.is_sorted = false; // 'inst' should be somewhere beneath 'top'
- this.objects.push(inst);
- }
- else
- {
- this.objects.push(inst);
- this.is_sorted = true;
- }
-;
- };
- RenderCell_.prototype.remove = function (inst)
- {
- this.pending_removal.add(inst);
- this.any_pending_removal = true;
- if (this.pending_removal.count() >= 30)
- this.flush_pending();
- };
- RenderCell_.prototype.flush_pending = function ()
- {
-;
- if (!this.any_pending_removal)
- return; // not changed
- if (this.pending_removal.count() === this.objects.length)
- {
- this.reset();
- return;
- }
- cr.arrayRemoveAllFromObjectSet(this.objects, this.pending_removal);
- this.pending_removal.clear();
- this.any_pending_removal = false;
- };
- function sortByInstanceZIndex(a, b)
- {
- return a.zindex - b.zindex;
- };
- RenderCell_.prototype.ensure_sorted = function ()
- {
- if (this.is_sorted)
- return; // already sorted
- this.objects.sort(sortByInstanceZIndex);
- this.is_sorted = true;
- };
- RenderCell_.prototype.reset = function ()
- {
- cr.clearArray(this.objects);
- this.is_sorted = true;
- this.pending_removal.clear();
- this.any_pending_removal = false;
- };
- RenderCell_.prototype.dump = function (result)
- {
- this.flush_pending();
- this.ensure_sorted();
- if (this.objects.length)
- result.push(this.objects);
- };
- cr.RenderCell = RenderCell_;
- var fxNames = [ "lighter",
- "xor",
- "copy",
- "destination-over",
- "source-in",
- "destination-in",
- "source-out",
- "destination-out",
- "source-atop",
- "destination-atop"];
- cr.effectToCompositeOp = function(effect)
- {
- if (effect <= 0 || effect >= 11)
- return "source-over";
- return fxNames[effect - 1]; // not including "none" so offset by 1
- };
- cr.setGLBlend = function(this_, effect, gl)
- {
- if (!gl)
- return;
- this_.srcBlend = gl.ONE;
- this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
- switch (effect) {
- case 1: // lighter (additive)
- this_.srcBlend = gl.ONE;
- this_.destBlend = gl.ONE;
- break;
- case 2: // xor
- break; // todo
- case 3: // copy
- this_.srcBlend = gl.ONE;
- this_.destBlend = gl.ZERO;
- break;
- case 4: // destination-over
- this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
- this_.destBlend = gl.ONE;
- break;
- case 5: // source-in
- this_.srcBlend = gl.DST_ALPHA;
- this_.destBlend = gl.ZERO;
- break;
- case 6: // destination-in
- this_.srcBlend = gl.ZERO;
- this_.destBlend = gl.SRC_ALPHA;
- break;
- case 7: // source-out
- this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
- this_.destBlend = gl.ZERO;
- break;
- case 8: // destination-out
- this_.srcBlend = gl.ZERO;
- this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
- break;
- case 9: // source-atop
- this_.srcBlend = gl.DST_ALPHA;
- this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
- break;
- case 10: // destination-atop
- this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
- this_.destBlend = gl.SRC_ALPHA;
- break;
- }
- };
- cr.round6dp = function (x)
- {
- return Math.round(x * 1000000) / 1000000;
- };
- /*
- var localeCompare_options = {
- "usage": "search",
- "sensitivity": "accent"
- };
- var has_localeCompare = !!"a".localeCompare;
- var localeCompare_works1 = (has_localeCompare && "a".localeCompare("A", undefined, localeCompare_options) === 0);
- var localeCompare_works2 = (has_localeCompare && "a".localeCompare("á", undefined, localeCompare_options) !== 0);
- var supports_localeCompare = (has_localeCompare && localeCompare_works1 && localeCompare_works2);
- */
- cr.equals_nocase = function (a, b)
- {
- if (typeof a !== "string" || typeof b !== "string")
- return false;
- if (a.length !== b.length)
- return false;
- if (a === b)
- return true;
- /*
- if (supports_localeCompare)
- {
- return (a.localeCompare(b, undefined, localeCompare_options) === 0);
- }
- else
- {
- */
- return a.toLowerCase() === b.toLowerCase();
- };
- cr.isCanvasInputEvent = function (e)
- {
- var target = e.target;
- if (!target)
- return true;
- if (target === document || target === window)
- return true;
- if (document && document.body && target === document.body)
- return true;
- if (cr.equals_nocase(target.tagName, "canvas"))
- return true;
- return false;
- };
-}());
-var MatrixArray=typeof Float32Array!=="undefined"?Float32Array:Array,glMatrixArrayType=MatrixArray,vec3={},mat3={},mat4={},quat4={};vec3.create=function(a){var b=new MatrixArray(3);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2]);return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a===c)return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a;c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c};
-vec3.subtract=function(a,b,c){if(!c||a===c)return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a;c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a===c)return a[0]*=b,a[1]*=b,a[2]*=b,a;c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c};
-vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g===1)return b[0]=c,b[1]=d,b[2]=e,b}else return b[0]=0,b[1]=0,b[2]=0,b;g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1],a=a[2],g=b[0],f=b[1],b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1],a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};
-vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1],a=a[2]-b[2],b=Math.sqrt(d*d+e*e+a*a);if(!b)return c[0]=0,c[1]=0,c[2]=0,c;b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};
-mat3.create=function(a){var b=new MatrixArray(9);a&&(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 b};mat3.set=function(a,b){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 b};mat3.identity=function(a){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 a};
-mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[15]=1;b[14]=0;b[13]=0;b[12]=0;b[11]=0;b[10]=a[8];b[9]=a[7];b[8]=a[6];b[7]=0;b[6]=a[5];b[5]=a[4];b[4]=a[3];b[3]=0;b[2]=a[2];b[1]=a[1];b[0]=a[0];return b};
-mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};mat4.create=function(a){var b=new MatrixArray(16);a&&(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],b[9]=a[9],b[10]=a[10],b[11]=a[11],b[12]=a[12],b[13]=a[13],b[14]=a[14],b[15]=a[15]);return b};
-mat4.set=function(a,b){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];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};
-mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b};
-mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],n=a[11],o=a[12],m=a[13],p=a[14],a=a[15];return o*k*h*e-j*m*h*e-o*f*l*e+g*m*l*e+j*f*p*e-g*k*p*e-o*k*d*i+j*m*d*i+o*c*l*i-b*m*l*i-j*c*p*i+b*k*p*i+o*f*d*n-g*m*d*n-o*c*h*n+b*m*h*n+g*c*p*n-b*f*p*n-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a};
-mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],n=a[10],o=a[11],m=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*m,y=k*r-n*m,z=k*s-o*m,C=l*r-n*p,D=l*s-o*p,E=n*s-o*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+n*v-o*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-m*w+r*t-s*B)*q;b[7]=(k*w-n*t+o*B)*q;b[8]=(f*D-h*z+j*x)*q;
-b[9]=(-c*D+d*z-g*x)*q;b[10]=(m*v-p*t+s*A)*q;b[11]=(-k*v+l*t-o*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-m*u+p*B-r*A)*q;b[15]=(k*u-l*B+n*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());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];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
-mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,n=-k*g+h*i,o=j*g-f*i,m=c*l+d*n+e*o;if(!m)return null;m=1/m;b||(b=mat3.create());b[0]=l*m;b[1]=(-k*d+e*j)*m;b[2]=(h*d-e*f)*m;b[3]=n*m;b[4]=(k*c-e*i)*m;b[5]=(-h*c+e*g)*m;b[6]=o*m;b[7]=(-j*c+d*i)*m;b[8]=(f*c-d*g)*m;return b};
-mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],n=a[9],o=a[10],m=a[11],p=a[12],r=a[13],s=a[14],a=a[15],A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14],b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*n+u*r;c[2]=A*g+B*j+t*o+u*s;c[3]=A*f+B*k+t*m+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*n+y*r;c[6]=v*g+w*j+x*o+y*s;c[7]=v*f+w*k+x*m+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*n+E*r;c[10]=z*g+C*
-j+D*o+E*s;c[11]=z*f+C*k+D*m+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*n+b*r;c[14]=q*g+F*j+G*o+b*s;c[15]=q*f+F*k+G*m+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c};
-mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c};
-mat4.translate=function(a,b,c){var d=b[0],e=b[1],b=b[2],g,f,h,i,j,k,l,n,o,m,p,r;if(!c||a===c)return a[12]=a[0]*d+a[4]*e+a[8]*b+a[12],a[13]=a[1]*d+a[5]*e+a[9]*b+a[13],a[14]=a[2]*d+a[6]*e+a[10]*b+a[14],a[15]=a[3]*d+a[7]*e+a[11]*b+a[15],a;g=a[0];f=a[1];h=a[2];i=a[3];j=a[4];k=a[5];l=a[6];n=a[7];o=a[8];m=a[9];p=a[10];r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=n;c[8]=o;c[9]=m;c[10]=p;c[11]=r;c[12]=g*d+j*e+o*b+a[12];c[13]=f*d+k*e+m*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+n*e+r*b+a[15];
-return c};mat4.scale=function(a,b,c){var d=b[0],e=b[1],b=b[2];if(!c||a===c)return a[0]*=d,a[1]*=d,a[2]*=d,a[3]*=d,a[4]*=e,a[5]*=e,a[6]*=e,a[7]*=e,a[8]*=b,a[9]*=b,a[10]*=b,a[11]*=b,a;c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c};
-mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1],c=c[2],f=Math.sqrt(e*e+g*g+c*c),h,i,j,k,l,n,o,m,p,r,s,A,B,t,u,v,w,x,y,z;if(!f)return null;f!==1&&(f=1/f,e*=f,g*=f,c*=f);h=Math.sin(b);i=Math.cos(b);j=1-i;b=a[0];f=a[1];k=a[2];l=a[3];n=a[4];o=a[5];m=a[6];p=a[7];r=a[8];s=a[9];A=a[10];B=a[11];t=e*e*j+i;u=g*e*j+c*h;v=c*e*j-g*h;w=e*g*j-c*h;x=g*g*j+i;y=c*g*j+e*h;z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;d?a!==d&&(d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]):d=a;d[0]=b*t+n*u+r*v;d[1]=f*t+o*u+s*v;d[2]=k*t+m*u+A*
-v;d[3]=l*t+p*u+B*v;d[4]=b*w+n*x+r*y;d[5]=f*w+o*x+s*y;d[6]=k*w+m*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+n*e+r*g;d[9]=f*z+o*e+s*g;d[10]=k*z+m*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c};
-mat4.rotateY=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c};
-mat4.rotateZ=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];c?a!==c&&(c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c};
-mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b*=a;return mat4.frustum(-b,b,-a,a,c,d,e)};
-mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f};
-mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e,g,f,h,i,j,k,l,n=a[0],o=a[1],a=a[2];g=c[0];f=c[1];e=c[2];c=b[1];j=b[2];if(n===b[0]&&o===c&&a===j)return mat4.identity(d);c=n-b[0];j=o-b[1];k=a-b[2];l=1/Math.sqrt(c*c+j*j+k*k);c*=l;j*=l;k*=l;b=f*k-e*j;e=e*c-g*k;g=g*j-f*c;(l=Math.sqrt(b*b+e*e+g*g))?(l=1/l,b*=l,e*=l,g*=l):g=e=b=0;f=j*g-k*e;h=k*b-c*g;i=c*e-j*b;(l=Math.sqrt(f*f+h*h+i*i))?(l=1/l,f*=l,h*=l,i*=l):i=h=f=0;d[0]=b;d[1]=f;d[2]=c;d[3]=0;d[4]=e;d[5]=h;d[6]=j;d[7]=0;d[8]=g;d[9]=i;d[10]=k;d[11]=
-0;d[12]=-(b*n+e*o+g*a);d[13]=-(f*n+h*o+i*a);d[14]=-(c*n+j*o+k*a);d[15]=1;return d};mat4.fromRotationTranslation=function(a,b,c){c||(c=mat4.create());var d=a[0],e=a[1],g=a[2],f=a[3],h=d+d,i=e+e,j=g+g,a=d*h,k=d*i;d*=j;var l=e*i;e*=j;g*=j;h*=f;i*=f;f*=j;c[0]=1-(l+g);c[1]=k+f;c[2]=d-i;c[3]=0;c[4]=k-f;c[5]=1-(a+g);c[6]=e+h;c[7]=0;c[8]=d+i;c[9]=e-h;c[10]=1-(a+l);c[11]=0;c[12]=b[0];c[13]=b[1];c[14]=b[2];c[15]=1;return c};
-mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4.create=function(a){var b=new MatrixArray(4);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3]);return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b};
-quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a===b)return a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e)),a;b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a===b)return a[0]*=-1,a[1]*=-1,a[2]*=-1,a;b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2],a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)};
-quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f===0)return b[0]=0,b[1]=0,b[2]=0,b[3]=0,b;f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],a=a[3],f=b[0],h=b[1],i=b[2],b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c};
-quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=a[0],f=a[1],h=a[2],a=a[3],i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d,d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=k-g;b[4]=1-(j+e);b[5]=d+f;b[6]=c+h;b[7]=d-f;b[8]=1-(j+l);return b};
-quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=0;b[4]=k-g;b[5]=1-(j+e);b[6]=d+f;b[7]=0;b[8]=c+h;b[9]=d-f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
-quat4.slerp=function(a,b,c,d){d||(d=a);var e=a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],g,f;if(Math.abs(e)>=1)return d!==a&&(d[0]=a[0],d[1]=a[1],d[2]=a[2],d[3]=a[3]),d;g=Math.acos(e);f=Math.sqrt(1-e*e);if(Math.abs(f)<0.001)return d[0]=a[0]*0.5+b[0]*0.5,d[1]=a[1]*0.5+b[1]*0.5,d[2]=a[2]*0.5+b[2]*0.5,d[3]=a[3]*0.5+b[3]*0.5,d;e=Math.sin((1-c)*g)/f;c=Math.sin(c*g)/f;d[0]=a[0]*e+b[0]*c;d[1]=a[1]*e+b[1]*c;d[2]=a[2]*e+b[2]*c;d[3]=a[3]*e+b[3]*c;return d};
-quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"};
-(function()
-{
- var MAX_VERTICES = 8000; // equates to 2500 objects being drawn
- var MAX_INDICES = (MAX_VERTICES / 2) * 3; // 6 indices for every 4 vertices
- var MAX_POINTS = 8000;
- var MULTI_BUFFERS = 4; // cycle 4 buffers to try and avoid blocking
- var BATCH_NULL = 0;
- var BATCH_QUAD = 1;
- var BATCH_SETTEXTURE = 2;
- var BATCH_SETOPACITY = 3;
- var BATCH_SETBLEND = 4;
- var BATCH_UPDATEMODELVIEW = 5;
- var BATCH_RENDERTOTEXTURE = 6;
- var BATCH_CLEAR = 7;
- var BATCH_POINTS = 8;
- var BATCH_SETPROGRAM = 9;
- var BATCH_SETPROGRAMPARAMETERS = 10;
- var BATCH_SETTEXTURE1 = 11;
- var BATCH_SETCOLOR = 12;
- var BATCH_SETDEPTHTEST = 13;
- var BATCH_SETEARLYZMODE = 14;
- /*
- var lose_ext = null;
- window.lose_context = function ()
- {
- if (!lose_ext)
- {
- console.log("WEBGL_lose_context not supported");
- return;
- }
- lose_ext.loseContext();
- };
- window.restore_context = function ()
- {
- if (!lose_ext)
- {
- console.log("WEBGL_lose_context not supported");
- return;
- }
- lose_ext.restoreContext();
- };
- */
- var tempMat4 = mat4.create();
- function GLWrap_(gl, isMobile, enableFrontToBack)
- {
- this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent);
- this.width = 0; // not yet known, wait for call to setSize()
- this.height = 0;
- this.enableFrontToBack = !!enableFrontToBack;
- this.isEarlyZPass = false;
- this.isBatchInEarlyZPass = false;
- this.currentZ = 0;
- this.zNear = 1;
- this.zFar = 1000;
- this.zIncrement = ((this.zFar - this.zNear) / 32768);
- this.zA = this.zFar / (this.zFar - this.zNear);
- this.zB = this.zFar * this.zNear / (this.zNear - this.zFar);
- this.kzA = 65536 * this.zA;
- this.kzB = 65536 * this.zB;
- this.cam = vec3.create([0, 0, 100]); // camera position
- this.look = vec3.create([0, 0, 0]); // lookat position
- this.up = vec3.create([0, 1, 0]); // up vector
- this.worldScale = vec3.create([1, 1, 1]); // world scaling factor
- this.enable_mipmaps = true;
- this.matP = mat4.create(); // perspective matrix
- this.matMV = mat4.create(); // model view matrix
- this.lastMV = mat4.create();
- this.currentMV = mat4.create();
- this.gl = gl;
- this.version = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0 ? 2 : 1);
- this.initState();
- };
- GLWrap_.prototype.initState = function ()
- {
- var gl = this.gl;
- var i, len;
- this.lastOpacity = 1;
- this.lastTexture0 = null; // last bound to TEXTURE0
- this.lastTexture1 = null; // last bound to TEXTURE1
- this.currentOpacity = 1;
- gl.clearColor(0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- gl.disable(gl.CULL_FACE);
- gl.disable(gl.STENCIL_TEST);
- gl.disable(gl.DITHER);
- if (this.enableFrontToBack)
- {
- gl.enable(gl.DEPTH_TEST);
- gl.depthFunc(gl.LEQUAL);
- }
- else
- {
- gl.disable(gl.DEPTH_TEST);
- }
- this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
- this.lastSrcBlend = gl.ONE;
- this.lastDestBlend = gl.ONE_MINUS_SRC_ALPHA;
- this.vertexData = new Float32Array(MAX_VERTICES * (this.enableFrontToBack ? 3 : 2));
- this.texcoordData = new Float32Array(MAX_VERTICES * 2);
- this.pointData = new Float32Array(MAX_POINTS * 4);
- this.pointBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, this.pointData.byteLength, gl.DYNAMIC_DRAW);
- this.vertexBuffers = new Array(MULTI_BUFFERS);
- this.texcoordBuffers = new Array(MULTI_BUFFERS);
- for (i = 0; i < MULTI_BUFFERS; i++)
- {
- this.vertexBuffers[i] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[i]);
- gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.DYNAMIC_DRAW);
- this.texcoordBuffers[i] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[i]);
- gl.bufferData(gl.ARRAY_BUFFER, this.texcoordData.byteLength, gl.DYNAMIC_DRAW);
- }
- this.curBuffer = 0;
- this.indexBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- var indexData = new Uint16Array(MAX_INDICES);
- i = 0, len = MAX_INDICES;
- var fv = 0;
- while (i < len)
- {
- indexData[i++] = fv; // top left
- indexData[i++] = fv + 1; // top right
- indexData[i++] = fv + 2; // bottom right (first tri)
- indexData[i++] = fv; // top left
- indexData[i++] = fv + 2; // bottom right
- indexData[i++] = fv + 3; // bottom left
- fv += 4;
- }
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
- this.vertexPtr = 0;
- this.texPtr = 0;
- this.pointPtr = 0;
- var fsSource, vsSource;
- this.shaderPrograms = [];
- fsSource = [
- "varying mediump vec2 vTex;",
- "uniform lowp float opacity;",
- "uniform lowp sampler2D samplerFront;",
- "void main(void) {",
- " gl_FragColor = texture2D(samplerFront, vTex);",
- " gl_FragColor *= opacity;",
- "}"
- ].join("\n");
- if (this.enableFrontToBack)
- {
- vsSource = [
- "attribute highp vec3 aPos;",
- "attribute mediump vec2 aTex;",
- "varying mediump vec2 vTex;",
- "uniform highp mat4 matP;",
- "uniform highp mat4 matMV;",
- "void main(void) {",
- " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, aPos.z, 1.0);",
- " vTex = aTex;",
- "}"
- ].join("\n");
- }
- else
- {
- vsSource = [
- "attribute highp vec2 aPos;",
- "attribute mediump vec2 aTex;",
- "varying mediump vec2 vTex;",
- "uniform highp mat4 matP;",
- "uniform highp mat4 matMV;",
- "void main(void) {",
- " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
- " vTex = aTex;",
- "}"
- ].join("\n");
- }
- var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "");
-;
- this.shaderPrograms.push(shaderProg); // Default shader is always shader 0
- fsSource = [
- "uniform mediump sampler2D samplerFront;",
- "varying lowp float opacity;",
- "void main(void) {",
- " gl_FragColor = texture2D(samplerFront, gl_PointCoord);",
- " gl_FragColor *= opacity;",
- "}"
- ].join("\n");
- var pointVsSource = [
- "attribute vec4 aPos;",
- "varying float opacity;",
- "uniform mat4 matP;",
- "uniform mat4 matMV;",
- "void main(void) {",
- " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
- " gl_PointSize = aPos.z;",
- " opacity = aPos.w;",
- "}"
- ].join("\n");
- shaderProg = this.createShaderProgram({src: fsSource}, pointVsSource, "");
-;
- this.shaderPrograms.push(shaderProg); // Point shader is always shader 1
- fsSource = [
- "varying mediump vec2 vTex;",
- "uniform lowp sampler2D samplerFront;",
- "void main(void) {",
- " if (texture2D(samplerFront, vTex).a < 1.0)",
- " discard;", // discarding non-opaque fragments
- "}"
- ].join("\n");
- var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "");
-;
- this.shaderPrograms.push(shaderProg); // Early-Z shader is always shader 2
- fsSource = [
- "uniform lowp vec4 colorFill;",
- "void main(void) {",
- " gl_FragColor = colorFill;",
- "}"
- ].join("\n");
- var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "");
-;
- this.shaderPrograms.push(shaderProg); // Fill-color shader is always shader 3
- for (var shader_name in cr.shaders)
- {
- if (cr.shaders.hasOwnProperty(shader_name))
- this.shaderPrograms.push(this.createShaderProgram(cr.shaders[shader_name], vsSource, shader_name));
- }
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, null);
- this.batch = [];
- this.batchPtr = 0;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- this.lastProgram = -1; // start -1 so first switchProgram can do work
- this.currentProgram = -1; // current program during batch execution
- this.currentShader = null;
- this.fbo = gl.createFramebuffer();
- this.renderToTex = null;
- this.depthBuffer = null;
- this.attachedDepthBuffer = false; // wait until first size call to attach, otherwise it has no storage
- if (this.enableFrontToBack)
- {
- this.depthBuffer = gl.createRenderbuffer();
- }
- this.tmpVec3 = vec3.create([0, 0, 0]);
-;
- var pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
- this.minPointSize = pointsizes[0];
- this.maxPointSize = pointsizes[1];
- if (this.maxPointSize > 2048)
- this.maxPointSize = 2048;
-;
- this.switchProgram(0);
- cr.seal(this);
- };
- function GLShaderProgram(gl, shaderProgram, name)
- {
- this.gl = gl;
- this.shaderProgram = shaderProgram;
- this.name = name;
- this.locAPos = gl.getAttribLocation(shaderProgram, "aPos");
- this.locATex = gl.getAttribLocation(shaderProgram, "aTex");
- this.locMatP = gl.getUniformLocation(shaderProgram, "matP");
- this.locMatMV = gl.getUniformLocation(shaderProgram, "matMV");
- this.locOpacity = gl.getUniformLocation(shaderProgram, "opacity");
- this.locColorFill = gl.getUniformLocation(shaderProgram, "colorFill");
- this.locSamplerFront = gl.getUniformLocation(shaderProgram, "samplerFront");
- this.locSamplerBack = gl.getUniformLocation(shaderProgram, "samplerBack");
- this.locDestStart = gl.getUniformLocation(shaderProgram, "destStart");
- this.locDestEnd = gl.getUniformLocation(shaderProgram, "destEnd");
- this.locSeconds = gl.getUniformLocation(shaderProgram, "seconds");
- this.locPixelWidth = gl.getUniformLocation(shaderProgram, "pixelWidth");
- this.locPixelHeight = gl.getUniformLocation(shaderProgram, "pixelHeight");
- this.locLayerScale = gl.getUniformLocation(shaderProgram, "layerScale");
- this.locLayerAngle = gl.getUniformLocation(shaderProgram, "layerAngle");
- this.locViewOrigin = gl.getUniformLocation(shaderProgram, "viewOrigin");
- this.locScrollPos = gl.getUniformLocation(shaderProgram, "scrollPos");
- this.hasAnyOptionalUniforms = !!(this.locPixelWidth || this.locPixelHeight || this.locSeconds || this.locSamplerBack || this.locDestStart || this.locDestEnd || this.locLayerScale || this.locLayerAngle || this.locViewOrigin || this.locScrollPos);
- this.lpPixelWidth = -999; // set to something unlikely so never counts as cached on first set
- this.lpPixelHeight = -999;
- this.lpOpacity = 1;
- this.lpDestStartX = 0.0;
- this.lpDestStartY = 0.0;
- this.lpDestEndX = 1.0;
- this.lpDestEndY = 1.0;
- this.lpLayerScale = 1.0;
- this.lpLayerAngle = 0.0;
- this.lpViewOriginX = 0.0;
- this.lpViewOriginY = 0.0;
- this.lpScrollPosX = 0.0;
- this.lpScrollPosY = 0.0;
- this.lpSeconds = 0.0;
- this.lastCustomParams = [];
- this.lpMatMV = mat4.create();
- if (this.locOpacity)
- gl.uniform1f(this.locOpacity, 1);
- if (this.locColorFill)
- gl.uniform4f(this.locColorFill, 1.0, 1.0, 1.0, 1.0);
- if (this.locSamplerFront)
- gl.uniform1i(this.locSamplerFront, 0);
- if (this.locSamplerBack)
- gl.uniform1i(this.locSamplerBack, 1);
- if (this.locDestStart)
- gl.uniform2f(this.locDestStart, 0.0, 0.0);
- if (this.locDestEnd)
- gl.uniform2f(this.locDestEnd, 1.0, 1.0);
- if (this.locLayerScale)
- gl.uniform1f(this.locLayerScale, 1.0);
- if (this.locLayerAngle)
- gl.uniform1f(this.locLayerAngle, 0.0);
- if (this.locViewOrigin)
- gl.uniform2f(this.locViewOrigin, 0.0, 0.0);
- if (this.locScrollPos)
- gl.uniform2f(this.locScrollPos, 0.0, 0.0);
- if (this.locSeconds)
- gl.uniform1f(this.locSeconds, 0.0);
- this.hasCurrentMatMV = false; // matMV needs updating
- };
- function areMat4sEqual(a, b)
- {
- return a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&
- a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&&
- a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&&
- a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15];
- };
- GLShaderProgram.prototype.updateMatMV = function (mv)
- {
- if (areMat4sEqual(this.lpMatMV, mv))
- return; // no change, save the expensive GL call
- mat4.set(mv, this.lpMatMV);
- this.gl.uniformMatrix4fv(this.locMatMV, false, mv);
- };
- GLWrap_.prototype.createShaderProgram = function(shaderEntry, vsSource, name)
- {
- var gl = this.gl;
- var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader, shaderEntry.src);
- gl.compileShader(fragmentShader);
- if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
- {
- var compilationlog = gl.getShaderInfoLog(fragmentShader);
- gl.deleteShader(fragmentShader);
- throw new Error("error compiling fragment shader: " + compilationlog);
- }
- var vertexShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertexShader, vsSource);
- gl.compileShader(vertexShader);
- if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
- {
- var compilationlog = gl.getShaderInfoLog(vertexShader);
- gl.deleteShader(fragmentShader);
- gl.deleteShader(vertexShader);
- throw new Error("error compiling vertex shader: " + compilationlog);
- }
- var shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, fragmentShader);
- gl.attachShader(shaderProgram, vertexShader);
- gl.linkProgram(shaderProgram);
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
- {
- var compilationlog = gl.getProgramInfoLog(shaderProgram);
- gl.deleteShader(fragmentShader);
- gl.deleteShader(vertexShader);
- gl.deleteProgram(shaderProgram);
- throw new Error("error linking shader program: " + compilationlog);
- }
- gl.useProgram(shaderProgram);
- gl.deleteShader(fragmentShader);
- gl.deleteShader(vertexShader);
- var ret = new GLShaderProgram(gl, shaderProgram, name);
- ret.extendBoxHorizontal = shaderEntry.extendBoxHorizontal || 0;
- ret.extendBoxVertical = shaderEntry.extendBoxVertical || 0;
- ret.crossSampling = !!shaderEntry.crossSampling;
- ret.preservesOpaqueness = !!shaderEntry.preservesOpaqueness;
- ret.animated = !!shaderEntry.animated;
- ret.parameters = shaderEntry.parameters || [];
- var i, len;
- for (i = 0, len = ret.parameters.length; i < len; i++)
- {
- ret.parameters[i][1] = gl.getUniformLocation(shaderProgram, ret.parameters[i][0]);
- ret.lastCustomParams.push(0);
- gl.uniform1f(ret.parameters[i][1], 0);
- }
- cr.seal(ret);
- return ret;
- };
- GLWrap_.prototype.getShaderIndex = function(name_)
- {
- var i, len;
- for (i = 0, len = this.shaderPrograms.length; i < len; i++)
- {
- if (this.shaderPrograms[i].name === name_)
- return i;
- }
- return -1;
- };
- GLWrap_.prototype.project = function (x, y, out)
- {
- var mv = this.matMV;
- var proj = this.matP;
- var fTempo = [0, 0, 0, 0, 0, 0, 0, 0];
- fTempo[0] = mv[0]*x+mv[4]*y+mv[12];
- fTempo[1] = mv[1]*x+mv[5]*y+mv[13];
- fTempo[2] = mv[2]*x+mv[6]*y+mv[14];
- fTempo[3] = mv[3]*x+mv[7]*y+mv[15];
- fTempo[4] = proj[0]*fTempo[0]+proj[4]*fTempo[1]+proj[8]*fTempo[2]+proj[12]*fTempo[3];
- fTempo[5] = proj[1]*fTempo[0]+proj[5]*fTempo[1]+proj[9]*fTempo[2]+proj[13]*fTempo[3];
- fTempo[6] = proj[2]*fTempo[0]+proj[6]*fTempo[1]+proj[10]*fTempo[2]+proj[14]*fTempo[3];
- fTempo[7] = -fTempo[2];
- if(fTempo[7]===0.0) //The w value
- return;
- fTempo[7]=1.0/fTempo[7];
- fTempo[4]*=fTempo[7];
- fTempo[5]*=fTempo[7];
- fTempo[6]*=fTempo[7];
- out[0]=(fTempo[4]*0.5+0.5)*this.width;
- out[1]=(fTempo[5]*0.5+0.5)*this.height;
- };
- GLWrap_.prototype.setSize = function(w, h, force)
- {
- if (this.width === w && this.height === h && !force)
- return;
- this.endBatch();
- var gl = this.gl;
- this.width = w;
- this.height = h;
- gl.viewport(0, 0, w, h);
- mat4.lookAt(this.cam, this.look, this.up, this.matMV);
- if (this.enableFrontToBack)
- {
- mat4.ortho(-w/2, w/2, h/2, -h/2, this.zNear, this.zFar, this.matP);
- this.worldScale[0] = 1;
- this.worldScale[1] = 1;
- }
- else
- {
- mat4.perspective(45, w / h, this.zNear, this.zFar, this.matP);
- var tl = [0, 0];
- var br = [0, 0];
- this.project(0, 0, tl);
- this.project(1, 1, br);
- this.worldScale[0] = 1 / (br[0] - tl[0]);
- this.worldScale[1] = -1 / (br[1] - tl[1]);
- }
- var i, len, s;
- for (i = 0, len = this.shaderPrograms.length; i < len; i++)
- {
- s = this.shaderPrograms[i];
- s.hasCurrentMatMV = false;
- if (s.locMatP)
- {
- gl.useProgram(s.shaderProgram);
- gl.uniformMatrix4fv(s.locMatP, false, this.matP);
- }
- }
- gl.useProgram(this.shaderPrograms[this.lastProgram].shaderProgram);
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.activeTexture(gl.TEXTURE0);
- this.lastTexture0 = null;
- this.lastTexture1 = null;
- if (this.depthBuffer)
- {
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);
- gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
- if (!this.attachedDepthBuffer)
- {
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);
- this.attachedDepthBuffer = true;
- }
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- this.renderToTex = null;
- }
- };
- GLWrap_.prototype.resetModelView = function ()
- {
- mat4.lookAt(this.cam, this.look, this.up, this.matMV);
- mat4.scale(this.matMV, this.worldScale);
- };
- GLWrap_.prototype.translate = function (x, y)
- {
- if (x === 0 && y === 0)
- return;
- this.tmpVec3[0] = x;// * this.worldScale[0];
- this.tmpVec3[1] = y;// * this.worldScale[1];
- this.tmpVec3[2] = 0;
- mat4.translate(this.matMV, this.tmpVec3);
- };
- GLWrap_.prototype.scale = function (x, y)
- {
- if (x === 1 && y === 1)
- return;
- this.tmpVec3[0] = x;
- this.tmpVec3[1] = y;
- this.tmpVec3[2] = 1;
- mat4.scale(this.matMV, this.tmpVec3);
- };
- GLWrap_.prototype.rotateZ = function (a)
- {
- if (a === 0)
- return;
- mat4.rotateZ(this.matMV, a);
- };
- GLWrap_.prototype.updateModelView = function()
- {
- if (areMat4sEqual(this.lastMV, this.matMV))
- return;
- var b = this.pushBatch();
- b.type = BATCH_UPDATEMODELVIEW;
- if (b.mat4param)
- mat4.set(this.matMV, b.mat4param);
- else
- b.mat4param = mat4.create(this.matMV);
- mat4.set(this.matMV, this.lastMV);
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- /*
- var debugBatch = false;
- jQuery(document).mousedown(
- function(info) {
- if (info.which === 2)
- debugBatch = true;
- }
- );
- */
- GLWrap_.prototype.setEarlyZIndex = function (i)
- {
- if (!this.enableFrontToBack)
- return;
- if (i > 32760)
- i = 32760;
- this.currentZ = this.cam[2] - this.zNear - i * this.zIncrement;
- };
- function GLBatchJob(type_, glwrap_)
- {
- this.type = type_;
- this.glwrap = glwrap_;
- this.gl = glwrap_.gl;
- this.opacityParam = 0; // for setOpacity()
- this.startIndex = 0; // for quad()
- this.indexCount = 0; // "
- this.texParam = null; // for setTexture()
- this.mat4param = null; // for updateModelView()
- this.shaderParams = []; // for user parameters
- cr.seal(this);
- };
- GLBatchJob.prototype.doSetEarlyZPass = function ()
- {
- var gl = this.gl;
- var glwrap = this.glwrap;
- if (this.startIndex !== 0) // enable
- {
- gl.depthMask(true); // enable depth writes
- gl.colorMask(false, false, false, false); // disable color writes
- gl.disable(gl.BLEND); // no color writes so disable blend
- gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
- gl.clear(gl.DEPTH_BUFFER_BIT); // auto-clear depth buffer
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- glwrap.isBatchInEarlyZPass = true;
- }
- else
- {
- gl.depthMask(false); // disable depth writes, only test existing depth values
- gl.colorMask(true, true, true, true); // enable color writes
- gl.enable(gl.BLEND); // turn blending back on
- glwrap.isBatchInEarlyZPass = false;
- }
- };
- GLBatchJob.prototype.doSetTexture = function ()
- {
- this.gl.bindTexture(this.gl.TEXTURE_2D, this.texParam);
- };
- GLBatchJob.prototype.doSetTexture1 = function ()
- {
- var gl = this.gl;
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, this.texParam);
- gl.activeTexture(gl.TEXTURE0);
- };
- GLBatchJob.prototype.doSetOpacity = function ()
- {
- var o = this.opacityParam;
- var glwrap = this.glwrap;
- glwrap.currentOpacity = o;
- var curProg = glwrap.currentShader;
- if (curProg.locOpacity && curProg.lpOpacity !== o)
- {
- curProg.lpOpacity = o;
- this.gl.uniform1f(curProg.locOpacity, o);
- }
- };
- GLBatchJob.prototype.doQuad = function ()
- {
- this.gl.drawElements(this.gl.TRIANGLES, this.indexCount, this.gl.UNSIGNED_SHORT, this.startIndex);
- };
- GLBatchJob.prototype.doSetBlend = function ()
- {
- this.gl.blendFunc(this.startIndex, this.indexCount);
- };
- GLBatchJob.prototype.doUpdateModelView = function ()
- {
- var i, len, s, shaderPrograms = this.glwrap.shaderPrograms, currentProgram = this.glwrap.currentProgram;
- for (i = 0, len = shaderPrograms.length; i < len; i++)
- {
- s = shaderPrograms[i];
- if (i === currentProgram && s.locMatMV)
- {
- s.updateMatMV(this.mat4param);
- s.hasCurrentMatMV = true;
- }
- else
- s.hasCurrentMatMV = false;
- }
- mat4.set(this.mat4param, this.glwrap.currentMV);
- };
- GLBatchJob.prototype.doRenderToTexture = function ()
- {
- var gl = this.gl;
- var glwrap = this.glwrap;
- if (this.texParam)
- {
- if (glwrap.lastTexture1 === this.texParam)
- {
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, null);
- glwrap.lastTexture1 = null;
- gl.activeTexture(gl.TEXTURE0);
- }
- gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
- if (!glwrap.isBatchInEarlyZPass)
- {
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texParam, 0);
- }
- }
- else
- {
- if (!glwrap.enableFrontToBack)
- {
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
- }
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- }
- };
- GLBatchJob.prototype.doClear = function ()
- {
- var gl = this.gl;
- var mode = this.startIndex;
- if (mode === 0) // clear whole surface
- {
- gl.clearColor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
- else if (mode === 1) // clear rectangle
- {
- gl.enable(gl.SCISSOR_TEST);
- gl.scissor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
- gl.clearColor(0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.disable(gl.SCISSOR_TEST);
- }
- else // clear depth
- {
- gl.clear(gl.DEPTH_BUFFER_BIT);
- }
- };
- GLBatchJob.prototype.doSetDepthTestEnabled = function ()
- {
- var gl = this.gl;
- var enable = this.startIndex;
- if (enable !== 0)
- {
- gl.enable(gl.DEPTH_TEST);
- }
- else
- {
- gl.disable(gl.DEPTH_TEST);
- }
- };
- GLBatchJob.prototype.doPoints = function ()
- {
- var gl = this.gl;
- var glwrap = this.glwrap;
- if (glwrap.enableFrontToBack)
- gl.disable(gl.DEPTH_TEST);
- var s = glwrap.shaderPrograms[1];
- gl.useProgram(s.shaderProgram);
- if (!s.hasCurrentMatMV && s.locMatMV)
- {
- s.updateMatMV(glwrap.currentMV);
- s.hasCurrentMatMV = true;
- }
- gl.enableVertexAttribArray(s.locAPos);
- gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.pointBuffer);
- gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
- gl.drawArrays(gl.POINTS, this.startIndex / 4, this.indexCount);
- s = glwrap.currentShader;
- gl.useProgram(s.shaderProgram);
- if (s.locAPos >= 0)
- {
- gl.enableVertexAttribArray(s.locAPos);
- gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
- gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
- }
- if (s.locATex >= 0)
- {
- gl.enableVertexAttribArray(s.locATex);
- gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
- gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
- }
- if (glwrap.enableFrontToBack)
- gl.enable(gl.DEPTH_TEST);
- };
- GLBatchJob.prototype.doSetProgram = function ()
- {
- var gl = this.gl;
- var glwrap = this.glwrap;
- var s = glwrap.shaderPrograms[this.startIndex]; // recycled param to save memory
- glwrap.currentProgram = this.startIndex; // current batch program
- glwrap.currentShader = s;
- gl.useProgram(s.shaderProgram); // switch to
- if (!s.hasCurrentMatMV && s.locMatMV)
- {
- s.updateMatMV(glwrap.currentMV);
- s.hasCurrentMatMV = true;
- }
- if (s.locOpacity && s.lpOpacity !== glwrap.currentOpacity)
- {
- s.lpOpacity = glwrap.currentOpacity;
- gl.uniform1f(s.locOpacity, glwrap.currentOpacity);
- }
- if (s.locAPos >= 0)
- {
- gl.enableVertexAttribArray(s.locAPos);
- gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
- gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
- }
- if (s.locATex >= 0)
- {
- gl.enableVertexAttribArray(s.locATex);
- gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
- gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
- }
- }
- GLBatchJob.prototype.doSetColor = function ()
- {
- var s = this.glwrap.currentShader;
- var mat4param = this.mat4param;
- this.gl.uniform4f(s.locColorFill, mat4param[0], mat4param[1], mat4param[2], mat4param[3]);
- };
- GLBatchJob.prototype.doSetProgramParameters = function ()
- {
- var i, len, s = this.glwrap.currentShader;
- var gl = this.gl;
- var mat4param = this.mat4param;
- if (s.locSamplerBack && this.glwrap.lastTexture1 !== this.texParam)
- {
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, this.texParam);
- this.glwrap.lastTexture1 = this.texParam;
- gl.activeTexture(gl.TEXTURE0);
- }
- var v = mat4param[0];
- var v2;
- if (s.locPixelWidth && v !== s.lpPixelWidth)
- {
- s.lpPixelWidth = v;
- gl.uniform1f(s.locPixelWidth, v);
- }
- v = mat4param[1];
- if (s.locPixelHeight && v !== s.lpPixelHeight)
- {
- s.lpPixelHeight = v;
- gl.uniform1f(s.locPixelHeight, v);
- }
- v = mat4param[2];
- v2 = mat4param[3];
- if (s.locDestStart && (v !== s.lpDestStartX || v2 !== s.lpDestStartY))
- {
- s.lpDestStartX = v;
- s.lpDestStartY = v2;
- gl.uniform2f(s.locDestStart, v, v2);
- }
- v = mat4param[4];
- v2 = mat4param[5];
- if (s.locDestEnd && (v !== s.lpDestEndX || v2 !== s.lpDestEndY))
- {
- s.lpDestEndX = v;
- s.lpDestEndY = v2;
- gl.uniform2f(s.locDestEnd, v, v2);
- }
- v = mat4param[6];
- if (s.locLayerScale && v !== s.lpLayerScale)
- {
- s.lpLayerScale = v;
- gl.uniform1f(s.locLayerScale, v);
- }
- v = mat4param[7];
- if (s.locLayerAngle && v !== s.lpLayerAngle)
- {
- s.lpLayerAngle = v;
- gl.uniform1f(s.locLayerAngle, v);
- }
- v = mat4param[8];
- v2 = mat4param[9];
- if (s.locViewOrigin && (v !== s.lpViewOriginX || v2 !== s.lpViewOriginY))
- {
- s.lpViewOriginX = v;
- s.lpViewOriginY = v2;
- gl.uniform2f(s.locViewOrigin, v, v2);
- }
- v = mat4param[10];
- v2 = mat4param[11];
- if (s.locScrollPos && (v !== s.lpScrollPosX || v2 !== s.lpScrollPosY))
- {
- s.lpScrollPosX = v;
- s.lpScrollPosY = v2;
- gl.uniform2f(s.locScrollPos, v, v2);
- }
- v = mat4param[12];
- if (s.locSeconds && v !== s.lpSeconds)
- {
- s.lpSeconds = v;
- gl.uniform1f(s.locSeconds, v);
- }
- if (s.parameters.length)
- {
- for (i = 0, len = s.parameters.length; i < len; i++)
- {
- v = this.shaderParams[i];
- if (v !== s.lastCustomParams[i])
- {
- s.lastCustomParams[i] = v;
- gl.uniform1f(s.parameters[i][1], v);
- }
- }
- }
- };
- GLWrap_.prototype.pushBatch = function ()
- {
- if (this.batchPtr === this.batch.length)
- this.batch.push(new GLBatchJob(BATCH_NULL, this));
- return this.batch[this.batchPtr++];
- };
- GLWrap_.prototype.endBatch = function ()
- {
- if (this.batchPtr === 0)
- return;
- if (this.gl.isContextLost())
- return;
- var gl = this.gl;
- if (this.pointPtr > 0)
- {
- gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.pointData.subarray(0, this.pointPtr));
- if (s && s.locAPos >= 0 && s.name === "")
- gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
- }
- if (this.vertexPtr > 0)
- {
- var s = this.currentShader;
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[this.curBuffer]);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexData.subarray(0, this.vertexPtr));
- if (s && s.locAPos >= 0 && s.name !== "")
- gl.vertexAttribPointer(s.locAPos, this.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
- gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[this.curBuffer]);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.texcoordData.subarray(0, this.texPtr));
- if (s && s.locATex >= 0 && s.name !== "")
- gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
- }
- var i, len, b;
- for (i = 0, len = this.batchPtr; i < len; i++)
- {
- b = this.batch[i];
- switch (b.type) {
- case 1:
- b.doQuad();
- break;
- case 2:
- b.doSetTexture();
- break;
- case 3:
- b.doSetOpacity();
- break;
- case 4:
- b.doSetBlend();
- break;
- case 5:
- b.doUpdateModelView();
- break;
- case 6:
- b.doRenderToTexture();
- break;
- case 7:
- b.doClear();
- break;
- case 8:
- b.doPoints();
- break;
- case 9:
- b.doSetProgram();
- break;
- case 10:
- b.doSetProgramParameters();
- break;
- case 11:
- b.doSetTexture1();
- break;
- case 12:
- b.doSetColor();
- break;
- case 13:
- b.doSetDepthTestEnabled();
- break;
- case 14:
- b.doSetEarlyZPass();
- break;
- }
- }
- this.batchPtr = 0;
- this.vertexPtr = 0;
- this.texPtr = 0;
- this.pointPtr = 0;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- this.isBatchInEarlyZPass = false;
- this.curBuffer++;
- if (this.curBuffer >= MULTI_BUFFERS)
- this.curBuffer = 0;
- };
- GLWrap_.prototype.setOpacity = function (op)
- {
- if (op === this.lastOpacity)
- return;
- if (this.isEarlyZPass)
- return; // ignore
- var b = this.pushBatch();
- b.type = BATCH_SETOPACITY;
- b.opacityParam = op;
- this.lastOpacity = op;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.setTexture = function (tex)
- {
- if (tex === this.lastTexture0)
- return;
-;
- var b = this.pushBatch();
- b.type = BATCH_SETTEXTURE;
- b.texParam = tex;
- this.lastTexture0 = tex;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.setBlend = function (s, d)
- {
- if (s === this.lastSrcBlend && d === this.lastDestBlend)
- return;
- if (this.isEarlyZPass)
- return; // ignore
- var b = this.pushBatch();
- b.type = BATCH_SETBLEND;
- b.startIndex = s; // recycle params to save memory
- b.indexCount = d;
- this.lastSrcBlend = s;
- this.lastDestBlend = d;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.isPremultipliedAlphaBlend = function ()
- {
- return (this.lastSrcBlend === this.gl.ONE && this.lastDestBlend === this.gl.ONE_MINUS_SRC_ALPHA);
- };
- GLWrap_.prototype.setAlphaBlend = function ()
- {
- this.setBlend(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
- };
- GLWrap_.prototype.setNoPremultiplyAlphaBlend = function ()
- {
- this.setBlend(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
- };
- var LAST_VERTEX = MAX_VERTICES * 2 - 8;
- GLWrap_.prototype.quad = function(tlx, tly, trx, try_, brx, bry, blx, bly)
- {
- if (this.vertexPtr >= LAST_VERTEX)
- this.endBatch();
- var v = this.vertexPtr; // vertex cursor
- var t = this.texPtr;
- var vd = this.vertexData; // vertex data array
- var td = this.texcoordData; // texture coord data array
- var currentZ = this.currentZ;
- if (this.hasQuadBatchTop)
- {
- this.batch[this.batchPtr - 1].indexCount += 6;
- }
- else
- {
- var b = this.pushBatch();
- b.type = BATCH_QUAD;
- b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
- b.indexCount = 6;
- this.hasQuadBatchTop = true;
- this.hasPointBatchTop = false;
- }
- if (this.enableFrontToBack)
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = currentZ;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = currentZ;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = currentZ;
- vd[v++] = blx;
- vd[v++] = bly;
- vd[v++] = currentZ;
- }
- else
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = blx;
- vd[v++] = bly;
- }
- td[t++] = 0;
- td[t++] = 0;
- td[t++] = 1;
- td[t++] = 0;
- td[t++] = 1;
- td[t++] = 1;
- td[t++] = 0;
- td[t++] = 1;
- this.vertexPtr = v;
- this.texPtr = t;
- };
- GLWrap_.prototype.quadTex = function(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex)
- {
- if (this.vertexPtr >= LAST_VERTEX)
- this.endBatch();
- var v = this.vertexPtr; // vertex cursor
- var t = this.texPtr;
- var vd = this.vertexData; // vertex data array
- var td = this.texcoordData; // texture coord data array
- var currentZ = this.currentZ;
- if (this.hasQuadBatchTop)
- {
- this.batch[this.batchPtr - 1].indexCount += 6;
- }
- else
- {
- var b = this.pushBatch();
- b.type = BATCH_QUAD;
- b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
- b.indexCount = 6;
- this.hasQuadBatchTop = true;
- this.hasPointBatchTop = false;
- }
- var rc_left = rcTex.left;
- var rc_top = rcTex.top;
- var rc_right = rcTex.right;
- var rc_bottom = rcTex.bottom;
- if (this.enableFrontToBack)
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = currentZ;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = currentZ;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = currentZ;
- vd[v++] = blx;
- vd[v++] = bly;
- vd[v++] = currentZ;
- }
- else
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = blx;
- vd[v++] = bly;
- }
- td[t++] = rc_left;
- td[t++] = rc_top;
- td[t++] = rc_right;
- td[t++] = rc_top;
- td[t++] = rc_right;
- td[t++] = rc_bottom;
- td[t++] = rc_left;
- td[t++] = rc_bottom;
- this.vertexPtr = v;
- this.texPtr = t;
- };
- GLWrap_.prototype.quadTexUV = function(tlx, tly, trx, try_, brx, bry, blx, bly, tlu, tlv, tru, trv, bru, brv, blu, blv)
- {
- if (this.vertexPtr >= LAST_VERTEX)
- this.endBatch();
- var v = this.vertexPtr; // vertex cursor
- var t = this.texPtr;
- var vd = this.vertexData; // vertex data array
- var td = this.texcoordData; // texture coord data array
- var currentZ = this.currentZ;
- if (this.hasQuadBatchTop)
- {
- this.batch[this.batchPtr - 1].indexCount += 6;
- }
- else
- {
- var b = this.pushBatch();
- b.type = BATCH_QUAD;
- b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
- b.indexCount = 6;
- this.hasQuadBatchTop = true;
- this.hasPointBatchTop = false;
- }
- if (this.enableFrontToBack)
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = currentZ;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = currentZ;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = currentZ;
- vd[v++] = blx;
- vd[v++] = bly;
- vd[v++] = currentZ;
- }
- else
- {
- vd[v++] = tlx;
- vd[v++] = tly;
- vd[v++] = trx;
- vd[v++] = try_;
- vd[v++] = brx;
- vd[v++] = bry;
- vd[v++] = blx;
- vd[v++] = bly;
- }
- td[t++] = tlu;
- td[t++] = tlv;
- td[t++] = tru;
- td[t++] = trv;
- td[t++] = bru;
- td[t++] = brv;
- td[t++] = blu;
- td[t++] = blv;
- this.vertexPtr = v;
- this.texPtr = t;
- };
- GLWrap_.prototype.convexPoly = function(pts)
- {
- var pts_count = pts.length / 2;
-;
- var tris = pts_count - 2; // 3 points = 1 tri, 4 points = 2 tris, 5 points = 3 tris etc.
- var last_tri = tris - 1;
- var p0x = pts[0];
- var p0y = pts[1];
- var i, i2, p1x, p1y, p2x, p2y, p3x, p3y;
- for (i = 0; i < tris; i += 2) // draw 2 triangles at a time
- {
- i2 = i * 2;
- p1x = pts[i2 + 2];
- p1y = pts[i2 + 3];
- p2x = pts[i2 + 4];
- p2y = pts[i2 + 5];
- if (i === last_tri)
- {
- this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y);
- }
- else
- {
- p3x = pts[i2 + 6];
- p3y = pts[i2 + 7];
- this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y);
- }
- }
- };
- var LAST_POINT = MAX_POINTS - 4;
- GLWrap_.prototype.point = function(x_, y_, size_, opacity_)
- {
- if (this.pointPtr >= LAST_POINT)
- this.endBatch();
- var p = this.pointPtr; // point cursor
- var pd = this.pointData; // point data array
- if (this.hasPointBatchTop)
- {
- this.batch[this.batchPtr - 1].indexCount++;
- }
- else
- {
- var b = this.pushBatch();
- b.type = BATCH_POINTS;
- b.startIndex = p;
- b.indexCount = 1;
- this.hasPointBatchTop = true;
- this.hasQuadBatchTop = false;
- }
- pd[p++] = x_;
- pd[p++] = y_;
- pd[p++] = size_;
- pd[p++] = opacity_;
- this.pointPtr = p;
- };
- GLWrap_.prototype.switchProgram = function (progIndex)
- {
- if (this.lastProgram === progIndex)
- return; // no change
- var shaderProg = this.shaderPrograms[progIndex];
- if (!shaderProg)
- {
- if (this.lastProgram === 0)
- return; // already on default shader
- progIndex = 0;
- shaderProg = this.shaderPrograms[0];
- }
- var b = this.pushBatch();
- b.type = BATCH_SETPROGRAM;
- b.startIndex = progIndex;
- this.lastProgram = progIndex;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.programUsesDest = function (progIndex)
- {
- var s = this.shaderPrograms[progIndex];
- return !!(s.locDestStart || s.locDestEnd);
- };
- GLWrap_.prototype.programUsesCrossSampling = function (progIndex)
- {
- var s = this.shaderPrograms[progIndex];
- return !!(s.locDestStart || s.locDestEnd || s.crossSampling);
- };
- GLWrap_.prototype.programPreservesOpaqueness = function (progIndex)
- {
- return this.shaderPrograms[progIndex].preservesOpaqueness;
- };
- GLWrap_.prototype.programExtendsBox = function (progIndex)
- {
- var s = this.shaderPrograms[progIndex];
- return s.extendBoxHorizontal !== 0 || s.extendBoxVertical !== 0;
- };
- GLWrap_.prototype.getProgramBoxExtendHorizontal = function (progIndex)
- {
- return this.shaderPrograms[progIndex].extendBoxHorizontal;
- };
- GLWrap_.prototype.getProgramBoxExtendVertical = function (progIndex)
- {
- return this.shaderPrograms[progIndex].extendBoxVertical;
- };
- GLWrap_.prototype.getProgramParameterType = function (progIndex, paramIndex)
- {
- return this.shaderPrograms[progIndex].parameters[paramIndex][2];
- };
- GLWrap_.prototype.programIsAnimated = function (progIndex)
- {
- return this.shaderPrograms[progIndex].animated;
- };
- GLWrap_.prototype.setProgramParameters = function (backTex, pixelWidth, pixelHeight, destStartX, destStartY, destEndX, destEndY, layerScale, layerAngle, viewOriginLeft, viewOriginTop, scrollPosX, scrollPosY, seconds, params)
- {
- var i, len;
- var s = this.shaderPrograms[this.lastProgram];
- var b, mat4param, shaderParams;
- if (s.hasAnyOptionalUniforms || params.length)
- {
- b = this.pushBatch();
- b.type = BATCH_SETPROGRAMPARAMETERS;
- if (b.mat4param)
- mat4.set(this.matMV, b.mat4param);
- else
- b.mat4param = mat4.create();
- mat4param = b.mat4param;
- mat4param[0] = pixelWidth;
- mat4param[1] = pixelHeight;
- mat4param[2] = destStartX;
- mat4param[3] = destStartY;
- mat4param[4] = destEndX;
- mat4param[5] = destEndY;
- mat4param[6] = layerScale;
- mat4param[7] = layerAngle;
- mat4param[8] = viewOriginLeft;
- mat4param[9] = viewOriginTop;
- mat4param[10] = scrollPosX;
- mat4param[11] = scrollPosY;
- mat4param[12] = seconds;
- if (s.locSamplerBack)
- {
-;
- b.texParam = backTex;
- }
- else
- b.texParam = null;
- if (params.length)
- {
- shaderParams = b.shaderParams;
- shaderParams.length = params.length;
- for (i = 0, len = params.length; i < len; i++)
- shaderParams[i] = params[i];
- }
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- }
- };
- GLWrap_.prototype.clear = function (r, g, b_, a)
- {
- var b = this.pushBatch();
- b.type = BATCH_CLEAR;
- b.startIndex = 0; // clear all mode
- if (!b.mat4param)
- b.mat4param = mat4.create();
- b.mat4param[0] = r;
- b.mat4param[1] = g;
- b.mat4param[2] = b_;
- b.mat4param[3] = a;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.clearRect = function (x, y, w, h)
- {
- if (w < 0 || h < 0)
- return; // invalid clear area
- var b = this.pushBatch();
- b.type = BATCH_CLEAR;
- b.startIndex = 1; // clear rect mode
- if (!b.mat4param)
- b.mat4param = mat4.create();
- b.mat4param[0] = x;
- b.mat4param[1] = y;
- b.mat4param[2] = w;
- b.mat4param[3] = h;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.clearDepth = function ()
- {
- var b = this.pushBatch();
- b.type = BATCH_CLEAR;
- b.startIndex = 2; // clear depth mode
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.setEarlyZPass = function (e)
- {
- if (!this.enableFrontToBack)
- return; // no depth buffer in use
- e = !!e;
- if (this.isEarlyZPass === e)
- return; // no change
- var b = this.pushBatch();
- b.type = BATCH_SETEARLYZMODE;
- b.startIndex = (e ? 1 : 0);
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- this.isEarlyZPass = e;
- this.renderToTex = null;
- if (this.isEarlyZPass)
- {
- this.switchProgram(2); // early Z program
- }
- else
- {
- this.switchProgram(0); // normal rendering
- }
- };
- GLWrap_.prototype.setDepthTestEnabled = function (e)
- {
- if (!this.enableFrontToBack)
- return; // no depth buffer in use
- var b = this.pushBatch();
- b.type = BATCH_SETDEPTHTEST;
- b.startIndex = (e ? 1 : 0);
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.fullscreenQuad = function ()
- {
- mat4.set(this.lastMV, tempMat4);
- this.resetModelView();
- this.updateModelView();
- var halfw = this.width / 2;
- var halfh = this.height / 2;
- this.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
- mat4.set(tempMat4, this.matMV);
- this.updateModelView();
- };
- GLWrap_.prototype.setColorFillMode = function (r_, g_, b_, a_)
- {
- this.switchProgram(3);
- var b = this.pushBatch();
- b.type = BATCH_SETCOLOR;
- if (!b.mat4param)
- b.mat4param = mat4.create();
- b.mat4param[0] = r_;
- b.mat4param[1] = g_;
- b.mat4param[2] = b_;
- b.mat4param[3] = a_;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- GLWrap_.prototype.setTextureFillMode = function ()
- {
-;
- this.switchProgram(0);
- };
- GLWrap_.prototype.restoreEarlyZMode = function ()
- {
-;
- this.switchProgram(2);
- };
- GLWrap_.prototype.present = function ()
- {
- this.endBatch();
- this.gl.flush();
- /*
- if (debugBatch)
- {
-;
- debugBatch = false;
- }
- */
- };
- function nextHighestPowerOfTwo(x) {
- --x;
- for (var i = 1; i < 32; i <<= 1) {
- x = x | x >> i;
- }
- return x + 1;
- }
- var all_textures = [];
- var textures_by_src = {};
- GLWrap_.prototype.contextLost = function ()
- {
- cr.clearArray(all_textures);
- textures_by_src = {};
- };
- var BF_RGBA8 = 0;
- var BF_RGB8 = 1;
- var BF_RGBA4 = 2;
- var BF_RGB5_A1 = 3;
- var BF_RGB565 = 4;
- GLWrap_.prototype.loadTexture = function (img, tiling, linearsampling, pixelformat, tiletype, nomip)
- {
- tiling = !!tiling;
- linearsampling = !!linearsampling;
- var tex_key = img.src + "," + tiling + "," + linearsampling + (tiling ? ("," + tiletype) : "");
- var webGL_texture = null;
- if (typeof img.src !== "undefined" && textures_by_src.hasOwnProperty(tex_key))
- {
- webGL_texture = textures_by_src[tex_key];
- webGL_texture.c2refcount++;
- return webGL_texture;
- }
- this.endBatch();
-;
- var gl = this.gl;
- var isPOT = (cr.isPOT(img.width) && cr.isPOT(img.height));
- webGL_texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
- gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
- var internalformat = gl.RGBA;
- var format = gl.RGBA;
- var type = gl.UNSIGNED_BYTE;
- if (pixelformat && !this.isIE)
- {
- switch (pixelformat) {
- case BF_RGB8:
- internalformat = gl.RGB;
- format = gl.RGB;
- break;
- case BF_RGBA4:
- type = gl.UNSIGNED_SHORT_4_4_4_4;
- break;
- case BF_RGB5_A1:
- type = gl.UNSIGNED_SHORT_5_5_5_1;
- break;
- case BF_RGB565:
- internalformat = gl.RGB;
- format = gl.RGB;
- type = gl.UNSIGNED_SHORT_5_6_5;
- break;
- }
- }
- if (this.version === 1 && !isPOT && tiling)
- {
- var canvas = document.createElement("canvas");
- canvas.width = cr.nextHighestPowerOfTwo(img.width);
- canvas.height = cr.nextHighestPowerOfTwo(img.height);
- var ctx = canvas.getContext("2d");
- if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
- {
- ctx["imageSmoothingEnabled"] = linearsampling;
- }
- else
- {
- ctx["webkitImageSmoothingEnabled"] = linearsampling;
- ctx["mozImageSmoothingEnabled"] = linearsampling;
- ctx["msImageSmoothingEnabled"] = linearsampling;
- }
- ctx.drawImage(img,
- 0, 0, img.width, img.height,
- 0, 0, canvas.width, canvas.height);
- gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, canvas);
- }
- else
- gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, img);
- if (tiling)
- {
- if (tiletype === "repeat-x")
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- }
- else if (tiletype === "repeat-y")
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- }
- else
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- }
- }
- else
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- }
- if (linearsampling)
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
- if ((isPOT || this.version >= 2) && this.enable_mipmaps && !nomip)
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
- gl.generateMipmap(gl.TEXTURE_2D);
- }
- else
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- }
- else
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- }
- gl.bindTexture(gl.TEXTURE_2D, null);
- this.lastTexture0 = null;
- webGL_texture.c2width = img.width;
- webGL_texture.c2height = img.height;
- webGL_texture.c2refcount = 1;
- webGL_texture.c2texkey = tex_key;
- all_textures.push(webGL_texture);
- textures_by_src[tex_key] = webGL_texture;
- return webGL_texture;
- };
- GLWrap_.prototype.createEmptyTexture = function (w, h, linearsampling, _16bit, tiling)
- {
- this.endBatch();
- var gl = this.gl;
- if (this.isIE)
- _16bit = false;
- var webGL_texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, null);
- if (tiling)
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- }
- else
- {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- }
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
- gl.bindTexture(gl.TEXTURE_2D, null);
- this.lastTexture0 = null;
- webGL_texture.c2width = w;
- webGL_texture.c2height = h;
- all_textures.push(webGL_texture);
- return webGL_texture;
- };
- GLWrap_.prototype.videoToTexture = function (video_, texture_, _16bit)
- {
- this.endBatch();
- var gl = this.gl;
- if (this.isIE)
- _16bit = false;
- gl.bindTexture(gl.TEXTURE_2D, texture_);
- gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
- try {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, video_);
- }
- catch (e)
- {
- if (console && console.error)
- console.error("Error updating WebGL texture: ", e);
- }
- gl.bindTexture(gl.TEXTURE_2D, null);
- this.lastTexture0 = null;
- };
- GLWrap_.prototype.deleteTexture = function (tex)
- {
- if (!tex)
- return;
- if (typeof tex.c2refcount !== "undefined" && tex.c2refcount > 1)
- {
- tex.c2refcount--;
- return;
- }
- this.endBatch();
- if (tex === this.lastTexture0)
- {
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- this.lastTexture0 = null;
- }
- if (tex === this.lastTexture1)
- {
- this.gl.activeTexture(this.gl.TEXTURE1);
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- this.gl.activeTexture(this.gl.TEXTURE0);
- this.lastTexture1 = null;
- }
- cr.arrayFindRemove(all_textures, tex);
- if (typeof tex.c2texkey !== "undefined")
- delete textures_by_src[tex.c2texkey];
- this.gl.deleteTexture(tex);
- };
- GLWrap_.prototype.estimateVRAM = function ()
- {
- var total = this.width * this.height * 4 * 2;
- var i, len, t;
- for (i = 0, len = all_textures.length; i < len; i++)
- {
- t = all_textures[i];
- total += (t.c2width * t.c2height * 4);
- }
- return total;
- };
- GLWrap_.prototype.textureCount = function ()
- {
- return all_textures.length;
- };
- GLWrap_.prototype.setRenderingToTexture = function (tex)
- {
- if (tex === this.renderToTex)
- return;
-;
- var b = this.pushBatch();
- b.type = BATCH_RENDERTOTEXTURE;
- b.texParam = tex;
- this.renderToTex = tex;
- this.hasQuadBatchTop = false;
- this.hasPointBatchTop = false;
- };
- cr.GLWrap = GLWrap_;
-}());
-;
-(function()
-{
- var raf = window["requestAnimationFrame"] ||
- window["mozRequestAnimationFrame"] ||
- window["webkitRequestAnimationFrame"] ||
- window["msRequestAnimationFrame"] ||
- window["oRequestAnimationFrame"];
- function Runtime(canvas)
- {
- if (!canvas || (!canvas.getContext && !canvas["dc"]))
- return;
- if (canvas["c2runtime"])
- return;
- else
- canvas["c2runtime"] = this;
- var self = this;
- this.isCrosswalk = /crosswalk/i.test(navigator.userAgent) || /xwalk/i.test(navigator.userAgent) || !!(typeof window["c2isCrosswalk"] !== "undefined" && window["c2isCrosswalk"]);
- this.isCordova = this.isCrosswalk || (typeof window["device"] !== "undefined" && (typeof window["device"]["cordova"] !== "undefined" || typeof window["device"]["phonegap"] !== "undefined")) || (typeof window["c2iscordova"] !== "undefined" && window["c2iscordova"]);
- this.isPhoneGap = this.isCordova;
- this.isDirectCanvas = !!canvas["dc"];
- this.isAppMobi = (typeof window["AppMobi"] !== "undefined" || this.isDirectCanvas);
- this.isCocoonJs = !!window["c2cocoonjs"];
- this.isEjecta = !!window["c2ejecta"];
- if (this.isCocoonJs)
- {
- CocoonJS["App"]["onSuspended"].addEventListener(function() {
- self["setSuspended"](true);
- });
- CocoonJS["App"]["onActivated"].addEventListener(function () {
- self["setSuspended"](false);
- });
- }
- if (this.isEjecta)
- {
- document.addEventListener("pagehide", function() {
- self["setSuspended"](true);
- });
- document.addEventListener("pageshow", function() {
- self["setSuspended"](false);
- });
- document.addEventListener("resize", function () {
- self["setSize"](window.innerWidth, window.innerHeight);
- });
- }
- this.isDomFree = (this.isDirectCanvas || this.isCocoonJs || this.isEjecta);
- this.isMicrosoftEdge = /edge\//i.test(navigator.userAgent);
- this.isIE = (/msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent) || /iemobile/i.test(navigator.userAgent)) && !this.isMicrosoftEdge;
- this.isTizen = /tizen/i.test(navigator.userAgent);
- this.isAndroid = /android/i.test(navigator.userAgent) && !this.isTizen && !this.isIE && !this.isMicrosoftEdge; // IE mobile and Tizen masquerade as Android
- this.isiPhone = (/iphone/i.test(navigator.userAgent) || /ipod/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // treat ipod as an iphone; IE mobile masquerades as iPhone
- this.isiPad = /ipad/i.test(navigator.userAgent);
- this.isiOS = this.isiPhone || this.isiPad || this.isEjecta;
- this.isiPhoneiOS6 = (this.isiPhone && /os\s6/i.test(navigator.userAgent));
- this.isChrome = (/chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // note true on Chromium-based webview on Android 4.4+; IE 'Edge' mode also pretends to be Chrome
- this.isAmazonWebApp = /amazonwebappplatform/i.test(navigator.userAgent);
- this.isFirefox = /firefox/i.test(navigator.userAgent);
- this.isSafari = /safari/i.test(navigator.userAgent) && !this.isChrome && !this.isIE && !this.isMicrosoftEdge; // Chrome and IE Mobile masquerade as Safari
- this.isWindows = /windows/i.test(navigator.userAgent);
- this.isNWjs = (typeof window["c2nodewebkit"] !== "undefined" || typeof window["c2nwjs"] !== "undefined" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent));
- this.isNodeWebkit = this.isNWjs; // old name for backwards compat
- this.isArcade = (typeof window["is_scirra_arcade"] !== "undefined");
- this.isWindows8App = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
- this.isWindows8Capable = !!(typeof window["c2isWindows8Capable"] !== "undefined" && window["c2isWindows8Capable"]);
- this.isWindowsPhone8 = !!(typeof window["c2isWindowsPhone8"] !== "undefined" && window["c2isWindowsPhone8"]);
- this.isWindowsPhone81 = !!(typeof window["c2isWindowsPhone81"] !== "undefined" && window["c2isWindowsPhone81"]);
- this.isWindows10 = !!window["cr_windows10"];
- this.isWinJS = (this.isWindows8App || this.isWindows8Capable || this.isWindowsPhone81 || this.isWindows10); // note not WP8.0
- this.isBlackberry10 = !!(typeof window["c2isBlackberry10"] !== "undefined" && window["c2isBlackberry10"]);
- this.isAndroidStockBrowser = (this.isAndroid && !this.isChrome && !this.isCrosswalk && !this.isFirefox && !this.isAmazonWebApp && !this.isDomFree);
- this.devicePixelRatio = 1;
- this.isMobile = (this.isCordova || this.isCrosswalk || this.isAppMobi || this.isCocoonJs || this.isAndroid || this.isiOS || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isBlackberry10 || this.isTizen || this.isEjecta);
- if (!this.isMobile)
- {
- this.isMobile = /(blackberry|bb10|playbook|palm|symbian|nokia|windows\s+ce|phone|mobile|tablet|kindle|silk)/i.test(navigator.userAgent);
- }
- this.isWKWebView = !!(this.isiOS && this.isCordova && window["webkit"]);
- if (typeof cr_is_preview !== "undefined" && !this.isNWjs && (window.location.search === "?nw" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent)))
- {
- this.isNWjs = true;
- }
- this.isDebug = (typeof cr_is_preview !== "undefined" && window.location.search.indexOf("debug") > -1);
- this.canvas = canvas;
- this.canvasdiv = document.getElementById("c2canvasdiv");
- this.gl = null;
- this.glwrap = null;
- this.glUnmaskedRenderer = "(unavailable)";
- this.enableFrontToBack = false;
- this.earlyz_index = 0;
- this.ctx = null;
- this.firstInFullscreen = false;
- this.oldWidth = 0; // for restoring non-fullscreen canvas after fullscreen
- this.oldHeight = 0;
- this.canvas.oncontextmenu = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
- this.canvas.onselectstart = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
- this.canvas.ontouchstart = function (e) { if(e.preventDefault) e.preventDefault(); return false; };
- if (this.isDirectCanvas)
- window["c2runtime"] = this;
- if (this.isNWjs)
- {
- window["ondragover"] = function(e) { e.preventDefault(); return false; };
- window["ondrop"] = function(e) { e.preventDefault(); return false; };
- if (window["nwgui"] && window["nwgui"]["App"]["clearCache"])
- window["nwgui"]["App"]["clearCache"]();
- }
- if (this.isAndroidStockBrowser && typeof jQuery !== "undefined")
- {
- jQuery("canvas").parents("*").css("overflow", "visible");
- }
- this.width = canvas.width;
- this.height = canvas.height;
- this.draw_width = this.width;
- this.draw_height = this.height;
- this.cssWidth = this.width;
- this.cssHeight = this.height;
- this.lastWindowWidth = window.innerWidth;
- this.lastWindowHeight = window.innerHeight;
- this.forceCanvasAlpha = false; // note: now unused, left for backwards compat since plugins could modify it
- this.redraw = true;
- this.isSuspended = false;
- if (!Date.now) {
- Date.now = function now() {
- return +new Date();
- };
- }
- this.plugins = [];
- this.types = {};
- this.types_by_index = [];
- this.behaviors = [];
- this.layouts = {};
- this.layouts_by_index = [];
- this.eventsheets = {};
- this.eventsheets_by_index = [];
- this.wait_for_textures = []; // for blocking until textures loaded
- this.triggers_to_postinit = [];
- this.all_global_vars = [];
- this.all_local_vars = [];
- this.solidBehavior = null;
- this.jumpthruBehavior = null;
- this.shadowcasterBehavior = null;
- this.deathRow = {};
- this.hasPendingInstances = false; // true if anything exists in create row or death row
- this.isInClearDeathRow = false;
- this.isInOnDestroy = 0; // needs to support recursion so increments and decrements and is true if > 0
- this.isRunningEvents = false;
- this.isEndingLayout = false;
- this.createRow = [];
- this.isLoadingState = false;
- this.saveToSlot = "";
- this.loadFromSlot = "";
- this.loadFromJson = null; // set to string when there is something to try to load
- this.lastSaveJson = "";
- this.signalledContinuousPreview = false;
- this.suspendDrawing = false; // for hiding display until continuous preview loads
- this.fireOnCreateAfterLoad = []; // for delaying "On create" triggers until loading complete
- this.dt = 0;
- this.dt1 = 0;
- this.minimumFramerate = 30;
- this.logictime = 0; // used to calculate CPUUtilisation
- this.cpuutilisation = 0;
- this.timescale = 1.0;
- this.kahanTime = new cr.KahanAdder();
- this.wallTime = new cr.KahanAdder();
- this.last_tick_time = 0;
- this.fps = 0;
- this.last_fps_time = 0;
- this.tickcount = 0;
- this.tickcount_nosave = 0; // same as tickcount but never saved/loaded
- this.execcount = 0;
- this.framecount = 0; // for fps
- this.objectcount = 0;
- this.changelayout = null;
- this.destroycallbacks = [];
- this.event_stack = [];
- this.event_stack_index = -1;
- this.localvar_stack = [[]];
- this.localvar_stack_index = 0;
- this.trigger_depth = 0; // recursion depth for triggers
- this.pushEventStack(null);
- this.loop_stack = [];
- this.loop_stack_index = -1;
- this.next_uid = 0;
- this.next_puid = 0; // permanent unique ids
- this.layout_first_tick = true;
- this.family_count = 0;
- this.suspend_events = [];
- this.raf_id = -1;
- this.timeout_id = -1;
- this.isloading = true;
- this.loadingprogress = 0;
- this.isNodeFullscreen = false;
- this.stackLocalCount = 0; // number of stack-based local vars for recursion
- this.audioInstance = null;
- this.had_a_click = false;
- this.isInUserInputEvent = false;
- this.objects_to_pretick = new cr.ObjectSet();
- this.objects_to_tick = new cr.ObjectSet();
- this.objects_to_tick2 = new cr.ObjectSet();
- this.registered_collisions = [];
- this.temp_poly = new cr.CollisionPoly([]);
- this.temp_poly2 = new cr.CollisionPoly([]);
- this.allGroups = []; // array of all event groups
- this.groups_by_name = {};
- this.cndsBySid = {};
- this.actsBySid = {};
- this.varsBySid = {};
- this.blocksBySid = {};
- this.running_layout = null; // currently running layout
- this.layer_canvas = null; // for layers "render-to-texture"
- this.layer_ctx = null;
- this.layer_tex = null;
- this.layout_tex = null;
- this.layout_canvas = null;
- this.layout_ctx = null;
- this.is_WebGL_context_lost = false;
- this.uses_background_blending = false; // if any shader uses background blending, so entire layout renders to texture
- this.fx_tex = [null, null];
- this.fullscreen_scaling = 0;
- this.files_subfolder = ""; // path with project files
- this.objectsByUid = {}; // maps every in-use UID (as a string) to its instance
- this.loaderlogos = null;
- this.snapshotCanvas = null;
- this.snapshotData = "";
- this.objectRefTable = [];
- this.requestProjectData();
- };
- Runtime.prototype.requestProjectData = function ()
- {
- var self = this;
- if (this.isWKWebView)
- {
- this.fetchLocalFileViaCordovaAsText("data.js", function (str)
- {
- self.loadProject(JSON.parse(str));
- }, function (err)
- {
- alert("Error fetching data.js");
- });
- return;
- }
- var xhr;
- if (this.isWindowsPhone8)
- xhr = new ActiveXObject("Microsoft.XMLHTTP");
- else
- xhr = new XMLHttpRequest();
- var datajs_filename = "data.js";
- if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isWindows10)
- datajs_filename = "data.json";
- xhr.open("GET", datajs_filename, true);
- var supportsJsonResponse = false;
- if (!this.isDomFree && ("response" in xhr) && ("responseType" in xhr))
- {
- try {
- xhr["responseType"] = "json";
- supportsJsonResponse = (xhr["responseType"] === "json");
- }
- catch (e) {
- supportsJsonResponse = false;
- }
- }
- if (!supportsJsonResponse && ("responseType" in xhr))
- {
- try {
- xhr["responseType"] = "text";
- }
- catch (e) {}
- }
- if ("overrideMimeType" in xhr)
- {
- try {
- xhr["overrideMimeType"]("application/json; charset=utf-8");
- }
- catch (e) {}
- }
- if (this.isWindowsPhone8)
- {
- xhr.onreadystatechange = function ()
- {
- if (xhr.readyState !== 4)
- return;
- self.loadProject(JSON.parse(xhr["responseText"]));
- };
- }
- else
- {
- xhr.onload = function ()
- {
- if (supportsJsonResponse)
- {
- self.loadProject(xhr["response"]); // already parsed by browser
- }
- else
- {
- if (self.isEjecta)
- {
- var str = xhr["responseText"];
- str = str.substr(str.indexOf("{")); // trim any BOM
- self.loadProject(JSON.parse(str));
- }
- else
- {
- self.loadProject(JSON.parse(xhr["responseText"])); // forced to sync parse JSON
- }
- }
- };
- xhr.onerror = function (e)
- {
- cr.logerror("Error requesting " + datajs_filename + ":");
- cr.logerror(e);
- };
- }
- xhr.send();
- };
- Runtime.prototype.initRendererAndLoader = function ()
- {
- var self = this;
- var i, len, j, lenj, k, lenk, t, s, l, y;
- this.isRetina = ((!this.isDomFree || this.isEjecta || this.isCordova) && this.useHighDpi && !this.isAndroidStockBrowser);
- if (this.fullscreen_mode === 0 && this.isiOS)
- this.isRetina = false;
- this.devicePixelRatio = (this.isRetina ? (window["devicePixelRatio"] || window["webkitDevicePixelRatio"] || window["mozDevicePixelRatio"] || window["msDevicePixelRatio"] || 1) : 1);
- if (typeof window["StatusBar"] === "object")
- window["StatusBar"]["hide"]();
- this.ClearDeathRow();
- var attribs;
- if (this.fullscreen_mode > 0)
- this["setSize"](window.innerWidth, window.innerHeight, true);
- this.canvas.addEventListener("webglcontextlost", function (ev) {
- ev.preventDefault();
- self.onContextLost();
- cr.logexport("[Construct 2] WebGL context lost");
- window["cr_setSuspended"](true); // stop rendering
- }, false);
- this.canvas.addEventListener("webglcontextrestored", function (ev) {
- self.glwrap.initState();
- self.glwrap.setSize(self.glwrap.width, self.glwrap.height, true);
- self.layer_tex = null;
- self.layout_tex = null;
- self.fx_tex[0] = null;
- self.fx_tex[1] = null;
- self.onContextRestored();
- self.redraw = true;
- cr.logexport("[Construct 2] WebGL context restored");
- window["cr_setSuspended"](false); // resume rendering
- }, false);
- try {
- if (this.enableWebGL && (this.isCocoonJs || this.isEjecta || !this.isDomFree))
- {
- attribs = {
- "alpha": true,
- "depth": false,
- "antialias": false,
- "powerPreference": "high-performance",
- "failIfMajorPerformanceCaveat": true
- };
- if (!this.isAndroid)
- this.gl = this.canvas.getContext("webgl2", attribs);
- if (!this.gl)
- {
- this.gl = (this.canvas.getContext("webgl", attribs) ||
- this.canvas.getContext("experimental-webgl", attribs));
- }
- }
- }
- catch (e) {
- }
- if (this.gl)
- {
- var isWebGL2 = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0);
- var debug_ext = this.gl.getExtension("WEBGL_debug_renderer_info");
- if (debug_ext)
- {
- var unmasked_vendor = this.gl.getParameter(debug_ext.UNMASKED_VENDOR_WEBGL);
- var unmasked_renderer = this.gl.getParameter(debug_ext.UNMASKED_RENDERER_WEBGL);
- this.glUnmaskedRenderer = unmasked_renderer + " [" + unmasked_vendor + "]";
- }
- if (this.enableFrontToBack)
- this.glUnmaskedRenderer += " [front-to-back enabled]";
-;
- if (!this.isDomFree)
- {
- this.overlay_canvas = document.createElement("canvas");
- jQuery(this.overlay_canvas).appendTo(this.canvas.parentNode);
- this.overlay_canvas.oncontextmenu = function (e) { return false; };
- this.overlay_canvas.onselectstart = function (e) { return false; };
- this.overlay_canvas.width = Math.round(this.cssWidth * this.devicePixelRatio);
- this.overlay_canvas.height = Math.round(this.cssHeight * this.devicePixelRatio);
- jQuery(this.overlay_canvas).css({"width": this.cssWidth + "px",
- "height": this.cssHeight + "px"});
- this.positionOverlayCanvas();
- this.overlay_ctx = this.overlay_canvas.getContext("2d");
- }
- this.glwrap = new cr.GLWrap(this.gl, this.isMobile, this.enableFrontToBack);
- this.glwrap.setSize(this.canvas.width, this.canvas.height);
- this.glwrap.enable_mipmaps = (this.downscalingQuality !== 0);
- this.ctx = null;
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
- {
- s = t.effect_types[j];
- s.shaderindex = this.glwrap.getShaderIndex(s.id);
- s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
- this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
- }
- }
- for (i = 0, len = this.layouts_by_index.length; i < len; i++)
- {
- l = this.layouts_by_index[i];
- for (j = 0, lenj = l.effect_types.length; j < lenj; j++)
- {
- s = l.effect_types[j];
- s.shaderindex = this.glwrap.getShaderIndex(s.id);
- s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
- }
- l.updateActiveEffects(); // update preserves opaqueness flag
- for (j = 0, lenj = l.layers.length; j < lenj; j++)
- {
- y = l.layers[j];
- for (k = 0, lenk = y.effect_types.length; k < lenk; k++)
- {
- s = y.effect_types[k];
- s.shaderindex = this.glwrap.getShaderIndex(s.id);
- s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
- this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
- }
- y.updateActiveEffects(); // update preserves opaqueness flag
- }
- }
- }
- else
- {
- if (this.fullscreen_mode > 0 && this.isDirectCanvas)
- {
-;
- this.canvas = null;
- document.oncontextmenu = function (e) { return false; };
- document.onselectstart = function (e) { return false; };
- this.ctx = AppMobi["canvas"]["getContext"]("2d");
- try {
- this.ctx["samplingMode"] = this.linearSampling ? "smooth" : "sharp";
- this.ctx["globalScale"] = 1;
- this.ctx["HTML5CompatibilityMode"] = true;
- this.ctx["imageSmoothingEnabled"] = this.linearSampling;
- } catch(e){}
- if (this.width !== 0 && this.height !== 0)
- {
- this.ctx.width = this.width;
- this.ctx.height = this.height;
- }
- }
- if (!this.ctx)
- {
-;
- if (this.isCocoonJs)
- {
- attribs = {
- "antialias": !!this.linearSampling,
- "alpha": true
- };
- this.ctx = this.canvas.getContext("2d", attribs);
- }
- else
- {
- attribs = {
- "alpha": true
- };
- this.ctx = this.canvas.getContext("2d", attribs);
- }
- this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
- }
- this.overlay_canvas = null;
- this.overlay_ctx = null;
- }
- this.tickFunc = function (timestamp) { self.tick(false, timestamp); };
- if (window != window.top && !this.isDomFree && !this.isWinJS && !this.isWindowsPhone8)
- {
- document.addEventListener("mousedown", function () {
- window.focus();
- }, true);
- document.addEventListener("touchstart", function () {
- window.focus();
- }, true);
- }
- if (typeof cr_is_preview !== "undefined")
- {
- if (this.isCocoonJs)
- console.log("[Construct 2] In preview-over-wifi via CocoonJS mode");
- if (window.location.search.indexOf("continuous") > -1)
- {
- cr.logexport("Reloading for continuous preview");
- this.loadFromSlot = "__c2_continuouspreview";
- this.suspendDrawing = true;
- }
- if (this.pauseOnBlur && !this.isMobile)
- {
- jQuery(window).focus(function ()
- {
- self["setSuspended"](false);
- });
- jQuery(window).blur(function ()
- {
- var parent = window.parent;
- if (!parent || !parent.document.hasFocus())
- self["setSuspended"](true);
- });
- }
- }
- window.addEventListener("blur", function () {
- self.onWindowBlur();
- });
- if (!this.isDomFree)
- {
- var unfocusFormControlFunc = function (e) {
- if (cr.isCanvasInputEvent(e) && document["activeElement"] && document["activeElement"] !== document.getElementsByTagName("body")[0] && document["activeElement"].blur)
- {
- try {
- document["activeElement"].blur();
- }
- catch (e) {}
- }
- }
- if (typeof PointerEvent !== "undefined")
- {
- document.addEventListener("pointerdown", unfocusFormControlFunc);
- }
- else if (window.navigator["msPointerEnabled"])
- {
- document.addEventListener("MSPointerDown", unfocusFormControlFunc);
- }
- else
- {
- document.addEventListener("touchstart", unfocusFormControlFunc);
- }
- document.addEventListener("mousedown", unfocusFormControlFunc);
- }
- if (this.fullscreen_mode === 0 && this.isRetina && this.devicePixelRatio > 1)
- {
- this["setSize"](this.original_width, this.original_height, true);
- }
- this.tryLockOrientation();
- this.getready(); // determine things to preload
- this.go(); // run loading screen
- this.extra = {};
- cr.seal(this);
- };
- var webkitRepaintFlag = false;
- Runtime.prototype["setSize"] = function (w, h, force)
- {
- var offx = 0, offy = 0;
- var neww = 0, newh = 0, intscale = 0;
- if (this.lastWindowWidth === w && this.lastWindowHeight === h && !force)
- return;
- this.lastWindowWidth = w;
- this.lastWindowHeight = h;
- var mode = this.fullscreen_mode;
- var orig_aspect, cur_aspect;
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen) && !this.isCordova;
- if (!isfullscreen && this.fullscreen_mode === 0 && !force)
- return; // ignore size events when not fullscreen and not using a fullscreen-in-browser mode
- if (isfullscreen)
- mode = this.fullscreen_scaling;
- var dpr = this.devicePixelRatio;
- if (mode >= 4)
- {
- if (mode === 5 && dpr !== 1) // integer scaling
- {
- w += 1;
- h += 1;
- }
- orig_aspect = this.original_width / this.original_height;
- cur_aspect = w / h;
- if (cur_aspect > orig_aspect)
- {
- neww = h * orig_aspect;
- if (mode === 5) // integer scaling
- {
- intscale = (neww * dpr) / this.original_width;
- if (intscale > 1)
- intscale = Math.floor(intscale);
- else if (intscale < 1)
- intscale = 1 / Math.ceil(1 / intscale);
- neww = this.original_width * intscale / dpr;
- newh = this.original_height * intscale / dpr;
- offx = (w - neww) / 2;
- offy = (h - newh) / 2;
- w = neww;
- h = newh;
- }
- else
- {
- offx = (w - neww) / 2;
- w = neww;
- }
- }
- else
- {
- newh = w / orig_aspect;
- if (mode === 5) // integer scaling
- {
- intscale = (newh * dpr) / this.original_height;
- if (intscale > 1)
- intscale = Math.floor(intscale);
- else if (intscale < 1)
- intscale = 1 / Math.ceil(1 / intscale);
- neww = this.original_width * intscale / dpr;
- newh = this.original_height * intscale / dpr;
- offx = (w - neww) / 2;
- offy = (h - newh) / 2;
- w = neww;
- h = newh;
- }
- else
- {
- offy = (h - newh) / 2;
- h = newh;
- }
- }
- }
- else if (isfullscreen && mode === 0)
- {
- offx = Math.floor((w - this.original_width) / 2);
- offy = Math.floor((h - this.original_height) / 2);
- w = this.original_width;
- h = this.original_height;
- }
- if (mode < 2)
- this.aspect_scale = dpr;
- this.cssWidth = Math.round(w);
- this.cssHeight = Math.round(h);
- this.width = Math.round(w * dpr);
- this.height = Math.round(h * dpr);
- this.redraw = true;
- if (this.wantFullscreenScalingQuality)
- {
- this.draw_width = this.width;
- this.draw_height = this.height;
- this.fullscreenScalingQuality = true;
- }
- else
- {
- if ((this.width < this.original_width && this.height < this.original_height) || mode === 1)
- {
- this.draw_width = this.width;
- this.draw_height = this.height;
- this.fullscreenScalingQuality = true;
- }
- else
- {
- this.draw_width = this.original_width;
- this.draw_height = this.original_height;
- this.fullscreenScalingQuality = false;
- /*var orig_aspect = this.original_width / this.original_height;
- var cur_aspect = this.width / this.height;
- if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
- this.aspect_scale = this.height / this.original_height;
- else
- this.aspect_scale = this.width / this.original_width;*/
- if (mode === 2) // scale inner
- {
- orig_aspect = this.original_width / this.original_height;
- cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
- if (cur_aspect < orig_aspect)
- this.draw_width = this.draw_height * cur_aspect;
- else if (cur_aspect > orig_aspect)
- this.draw_height = this.draw_width / cur_aspect;
- }
- else if (mode === 3)
- {
- orig_aspect = this.original_width / this.original_height;
- cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
- if (cur_aspect > orig_aspect)
- this.draw_width = this.draw_height * cur_aspect;
- else if (cur_aspect < orig_aspect)
- this.draw_height = this.draw_width / cur_aspect;
- }
- }
- }
- if (this.canvasdiv && !this.isDomFree)
- {
- jQuery(this.canvasdiv).css({"width": Math.round(w) + "px",
- "height": Math.round(h) + "px",
- "margin-left": Math.floor(offx) + "px",
- "margin-top": Math.floor(offy) + "px"});
- if (typeof cr_is_preview !== "undefined")
- {
- jQuery("#borderwrap").css({"width": Math.round(w) + "px",
- "height": Math.round(h) + "px"});
- }
- }
- if (this.canvas)
- {
- this.canvas.width = Math.round(w * dpr);
- this.canvas.height = Math.round(h * dpr);
- if (this.isEjecta)
- {
- this.canvas.style.left = Math.floor(offx) + "px";
- this.canvas.style.top = Math.floor(offy) + "px";
- this.canvas.style.width = Math.round(w) + "px";
- this.canvas.style.height = Math.round(h) + "px";
- }
- else if (this.isRetina && !this.isDomFree)
- {
- this.canvas.style.width = Math.round(w) + "px";
- this.canvas.style.height = Math.round(h) + "px";
- }
- }
- if (this.overlay_canvas)
- {
- this.overlay_canvas.width = Math.round(w * dpr);
- this.overlay_canvas.height = Math.round(h * dpr);
- this.overlay_canvas.style.width = this.cssWidth + "px";
- this.overlay_canvas.style.height = this.cssHeight + "px";
- }
- if (this.glwrap)
- {
- this.glwrap.setSize(Math.round(w * dpr), Math.round(h * dpr));
- }
- if (this.isDirectCanvas && this.ctx)
- {
- this.ctx.width = Math.round(w);
- this.ctx.height = Math.round(h);
- }
- if (this.ctx)
- {
- this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
- }
- this.tryLockOrientation();
- if (this.isiPhone && !this.isCordova)
- {
- window.scrollTo(0, 0);
- }
- };
- Runtime.prototype.tryLockOrientation = function ()
- {
- if (!this.autoLockOrientation || this.orientations === 0)
- return;
- var orientation = "portrait";
- if (this.orientations === 2)
- orientation = "landscape";
- try {
- if (screen["orientation"] && screen["orientation"]["lock"])
- screen["orientation"]["lock"](orientation).catch(function(){});
- else if (screen["lockOrientation"])
- screen["lockOrientation"](orientation);
- else if (screen["webkitLockOrientation"])
- screen["webkitLockOrientation"](orientation);
- else if (screen["mozLockOrientation"])
- screen["mozLockOrientation"](orientation);
- else if (screen["msLockOrientation"])
- screen["msLockOrientation"](orientation);
- }
- catch (e)
- {
- if (console && console.warn)
- console.warn("Failed to lock orientation: ", e);
- }
- };
- Runtime.prototype.onContextLost = function ()
- {
- this.glwrap.contextLost();
- this.is_WebGL_context_lost = true;
- var i, len, t;
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- if (t.onLostWebGLContext)
- t.onLostWebGLContext();
- }
- };
- Runtime.prototype.onContextRestored = function ()
- {
- this.is_WebGL_context_lost = false;
- var i, len, t;
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- if (t.onRestoreWebGLContext)
- t.onRestoreWebGLContext();
- }
- };
- Runtime.prototype.positionOverlayCanvas = function()
- {
- if (this.isDomFree)
- return;
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
- var overlay_position = isfullscreen ? jQuery(this.canvas).offset() : jQuery(this.canvas).position();
- overlay_position.position = "absolute";
- jQuery(this.overlay_canvas).css(overlay_position);
- };
- var caf = window["cancelAnimationFrame"] ||
- window["mozCancelAnimationFrame"] ||
- window["webkitCancelAnimationFrame"] ||
- window["msCancelAnimationFrame"] ||
- window["oCancelAnimationFrame"];
- Runtime.prototype["setSuspended"] = function (s)
- {
- var i, len;
- var self = this;
- if (s && !this.isSuspended)
- {
- cr.logexport("[Construct 2] Suspending");
- this.isSuspended = true; // next tick will be last
- if (this.raf_id !== -1 && caf) // note: CocoonJS does not implement cancelAnimationFrame
- caf(this.raf_id);
- if (this.timeout_id !== -1)
- clearTimeout(this.timeout_id);
- for (i = 0, len = this.suspend_events.length; i < len; i++)
- this.suspend_events[i](true);
- }
- else if (!s && this.isSuspended)
- {
- cr.logexport("[Construct 2] Resuming");
- this.isSuspended = false;
- this.last_tick_time = cr.performance_now(); // ensure first tick is a zero-dt one
- this.last_fps_time = cr.performance_now(); // reset FPS counter
- this.framecount = 0;
- this.logictime = 0;
- for (i = 0, len = this.suspend_events.length; i < len; i++)
- this.suspend_events[i](false);
- this.tick(false); // kick off runtime again
- }
- };
- Runtime.prototype.addSuspendCallback = function (f)
- {
- this.suspend_events.push(f);
- };
- Runtime.prototype.GetObjectReference = function (i)
- {
-;
- return this.objectRefTable[i];
- };
- Runtime.prototype.loadProject = function (data_response)
- {
-;
- if (!data_response || !data_response["project"])
- cr.logerror("Project model unavailable");
- var pm = data_response["project"];
- this.name = pm[0];
- this.first_layout = pm[1];
- this.fullscreen_mode = pm[12]; // 0 = off, 1 = crop, 2 = scale inner, 3 = scale outer, 4 = letterbox scale, 5 = integer letterbox scale
- this.fullscreen_mode_set = pm[12];
- this.original_width = pm[10];
- this.original_height = pm[11];
- this.parallax_x_origin = this.original_width / 2;
- this.parallax_y_origin = this.original_height / 2;
- if (this.isDomFree && !this.isEjecta && (pm[12] >= 4 || pm[12] === 0))
- {
- cr.logexport("[Construct 2] Letterbox scale fullscreen modes are not supported on this platform - falling back to 'Scale outer'");
- this.fullscreen_mode = 3;
- this.fullscreen_mode_set = 3;
- }
- this.uses_loader_layout = pm[18];
- this.loaderstyle = pm[19];
- if (this.loaderstyle === 0)
- {
- var loaderImage = new Image();
- loaderImage.crossOrigin = "anonymous";
- this.setImageSrc(loaderImage, "loading-logo.png");
- this.loaderlogos = {
- logo: loaderImage
- };
- }
- else if (this.loaderstyle === 4) // c2 splash
- {
- var loaderC2logo_1024 = new Image();
- loaderC2logo_1024.src = "data:image/png;base64,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";
- var loaderC2logo_512 = new Image();
- loaderC2logo_512.src = "data:image/png;base64,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";
- var loaderC2logo_256 = new Image();
- loaderC2logo_256.src = "data:image/png;base64,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";
- var loaderC2logo_128 = new Image();
- loaderC2logo_128.src = "data:image/png;base64,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";
- var loaderPowered_1024 = new Image();
- loaderPowered_1024.src = "data:image/png;base64,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";
- var loaderPowered_512 = new Image();
- loaderPowered_512.src = "data:image/png;base64,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";
- var loaderPowered_256 = new Image();
- loaderPowered_256.src = "data:image/png;base64,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";
- var loaderPowered_128 = new Image();
- loaderPowered_128.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAgCAMAAADt/IAXAAACEFBMVEUzMzN9g3g0NDR7gXdzeG9CQ0E1NTWBh3w6OzpvdGx9g3k6OjlkaGFLTUqEi394fXRvdGt1enE2NjZ3fXM9Pj1iZl+AhntVWFNjZ2BWWVQ4OTh1e3FwdWxpbmZAQT83Nzc4ODdrcGhuc2tMTkpKTElNT0tRVE9aXVdPUU1PUk42NzZ6gHZLTUk7PDs5OjldYFp0eXB+hHlYW1Z0enBeYlx+hHp5f3WAh3w2NjVtcmpqb2dMTktISkd/hntHSUY4ODhmamNdYVtnbGRBQkA3ODdyd25yeG88PTs7OzpQUk5ERkNZXFdhZV5eYVuCiX03NzY1NjVOUU2Din5ERUM/QD9uc2pma2N+hXpUV1JFR0Q0NTRDREKIj4OCiH1XWlVGSEVfY1w9Pjw+Pz0/QD6Ein92fHI7PDpdYVp8gniFjIA8PTyAhnxgY11gZF5FRkRQU05YXFZna2NCREFSVVFAQkB/hXpXW1Vrb2dJSkc9PTxlamKFi4BISUZZXVeHjoJzeW9gZF1TVlFfYlxna2RVV1JcX1lbX1lNUEyDiX5tcmlzeXB8gndRVFBOUExpbWZSVFBNT0xhZF5laWJ4fXNwdW1RU09bXllDRUJqbmZfY12Ei4BUVlJbXlhKTEhTVVFcYFpeYltxdm1xd25obGU1NTSFjIFKS0iBiHxscWl9hHlscGhpbWVaXVhvc2ttcWk0NDPL7ZluAAAChElEQVR4Xu3SU6+kWRxG8fWibNvHtm3bdtu27bFtfsXJ6a5UMkklXdU5yZlMat09++Kf38Xmf1mmTJnmnwOAuN3FvpT1fhyw5OVdygBETYlekvStAEUfCKYDBXD+KTAWVQOxduDDMu13WcCx1dLCNpifFrZXRCBoXi4fyk4AggGnKqCmxOwFaDyaImBJ7td1TleK4KlubA1GfHXkdAOx658DnwzCbctAONb8AGTTewN2DOXZrYs+B/TVfhEadUkJgK9RqWszLWBxAfhXUgV8CYxpsyneUgBizx/orhTAqYYocOQsCqcXiEkgRwDluVVAPXGYow0AHyUARYBY089cJaA7pE4V4AV4pcejAeClCSwGxNk+VQiFAMccAKKxFzkfMNgA0ORge5bkDwy3ETZugidKWoC5KO5PAbB/Bl+7afETyWNQD/VP5N1+/Bh5HKhQvZ5HTqJaTAL4SgO/fwOP89MD3DKjrwKg9xBMFuK4S34AvwHM9xSvs74B5Na/mTpUp5MAzmigScvhkbr0AO0z5F4A4KIENF+S1ISaR1VWuFxFvNeAE2XEs2UnAZTOAMLVazOkDNgEsOUQnFADBIaADscNoH7YDBSVWwGUcUCJURGfN78HcCUAxwFMJ4DSO7aW1AHyBgtr0hi4LXaU96t1QJ6xAnjx0APwyF+M6Po2DqDi4CQ0FXrZUXl+EPMOJgC+FkLuGiWwbhRIHfBTpTDSvQGIudXan39ZBwj/age8WjuAcs0p1DbsQMQAwAtp1ll2HFDIxtqOpt/igJqpP5e3/ioGoKcqDYCXOivxukSSFv73e4HyLVeFqbQAe16Whf0EdI5rDaTc33ore9wBzTj/0TJlyvQPsTd0lRaZaakAAAAASUVORK5CYII=";
- var loaderWebsite_1024 = new Image();
- loaderWebsite_1024.src = "data:image/png;base64,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";
- var loaderWebsite_512 = new Image();
- loaderWebsite_512.src = "data:image/png;base64,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";
- var loaderWebsite_256 = new Image();
- loaderWebsite_256.src = "data:image/png;base64,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";
- var loaderWebsite_128 = new Image();
- loaderWebsite_128.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAAgCAMAAADt/IAXAAABblBMVEUzMzM2NjY4ODheYlxAQkA/QD58gng0NDQ5Ojl6gHaCiX59hHlMTktZXFc9Pj15f3VkaGFdYVuEi39WWVQ8PTxgZF5FRkRtcmo1NTVlaWJscWl4fnSBiH1xdm5iZmBqb2c9Pjx2fHJcYFpYW1Y6Ozp9g3lHSEZcX1mAhnt+hXo3NzdSVFCHjoJGSEVAQT9CQ0FERUNZXFZobWVERkOAh3xUVlI8PDt1enF3fHNiZl9DREJ2e3I3ODdRVE+FjIE4ODdOUU2Din9KTElVWFNJS0hxdm1MTkpna2RbX1lQUk5XWlV7gXd8gndrcGhuc2tfY11tcml0eXBNUEyDin5yeG9ISkc1NjVmamOEi4BKTEhvdGx6gHVLTUp0enBwdWxNT0x4fXR4fXNVV1M+Pz5aXVhbXlhPUk5vdGs7PDs/QD9pbmZTVVGIj4NXWlRgZF1pbWY5OTlhZV9TVlFlamJzeXB/hntscWg0NDNeYluBiHw6JP9nAAAC8ElEQVR4Xu3R1YpsORhA4bVdyt3dXdvd3e2467jL2w+himloai7m6nCgvos/yWYTFoSv3tTUlFzky/pxhy+rGOQrZ0YM4NsCQEY7cAF80wEGMZTHwKz4gZkthNk7Sz8PA6xclOZmxBqA3stA4gkrb9ZzHviQKiUUibF2Rre8JiDlX+s7u0D4zN3XPUq0GDs6upOB4zKQcwCabbR0QG0qgOKlsgd839wGnq8DSKVK0Zyxu5B/FV4O587A54X+q3hLw5dI3ajsv25JWiTOSGc4YwZDR3WiF3FV3i0VwGldb8uDRCy3YmqRCJBWIGjNdyFwgpHUoJLxAEvPWKwBOxkvrD1aA9h+ChBKE7yaBT755VHAnAH4HBJQVQF51UTgRQHgNEDhuQG0/UGczTaw+Z0TKDaXYXMJDkMVBeINyARgXj3WkDck+F1FdmQd4EwhqLaGwFYEwZUdBbwD8MX4V7KNIK3+BHBzSe4DQqSAMwfwdtUA2NDgdsMkFVY9GMkiNCIELUIu1k+BvQKNGEtdvC4EAsPzgBsILTAyCnCNd8Lgh/jHj6ujADXJ2NVnxpHOOQC3H8EWn08P5BJYWngJMG3jUCF8QSwArD8h/ph3CpbKiOT82ZGRCIX+K8Bn/dJxu+1xwJAx/1uEyq8TArb2Gl5QXJU8wFw5NYBS8TgLLNtyLYrmCercu91RKGQQzOjDgOyGef8EyE0JQFrDs4nQ358QkHXEb2Dxt+sBQN6rA2mfByG10AcS4m7hfQ/g8A/UpAQYQ+1hQMsB4B4/AbkDgLTC2QmAaXcmBOBxGIClI3T9aaBshxBc/ksgbz+DbgPKwzK4PVvQj8vU7855GFBPBgzK848W+bOXhe1aGC6rWWTdFyV4HWNSQD59PyFRBoxEC6GtS4Aq5ntRvjtfdThcQDRU1asLEvQUWHgD0PsLIJy4SqYWXzip114Cu55aNdUBZk/+LtX2DdiMAAQthKdu/q/bOmNrTCZFJx+NZSaYmpqamvoHZD1hKSAldSkAAAAASUVORK5CYII=";
- this.loaderlogos = {
- logo: [loaderC2logo_1024, loaderC2logo_512, loaderC2logo_256, loaderC2logo_128],
- powered: [loaderPowered_1024, loaderPowered_512, loaderPowered_256, loaderPowered_128],
- website: [loaderWebsite_1024, loaderWebsite_512, loaderWebsite_256, loaderWebsite_128]
- };
- }
- this.next_uid = pm[21];
- this.objectRefTable = cr.getObjectRefTable();
- this.system = new cr.system_object(this);
- var i, len, j, lenj, k, lenk, idstr, m, b, t, f, p;
- var plugin, plugin_ctor;
- for (i = 0, len = pm[2].length; i < len; i++)
- {
- m = pm[2][i];
- p = this.GetObjectReference(m[0]);
-;
- cr.add_common_aces(m, p.prototype);
- plugin = new p(this);
- plugin.singleglobal = m[1];
- plugin.is_world = m[2];
- plugin.is_rotatable = m[5];
- plugin.must_predraw = m[9];
- if (plugin.onCreate)
- plugin.onCreate(); // opportunity to override default ACEs
- cr.seal(plugin);
- this.plugins.push(plugin);
- }
- this.objectRefTable = cr.getObjectRefTable();
- for (i = 0, len = pm[3].length; i < len; i++)
- {
- m = pm[3][i];
- plugin_ctor = this.GetObjectReference(m[1]);
-;
- plugin = null;
- for (j = 0, lenj = this.plugins.length; j < lenj; j++)
- {
- if (this.plugins[j] instanceof plugin_ctor)
- {
- plugin = this.plugins[j];
- break;
- }
- }
-;
-;
- var type_inst = new plugin.Type(plugin);
-;
- type_inst.name = m[0];
- type_inst.is_family = m[2];
- type_inst.instvar_sids = m[3].slice(0);
- type_inst.vars_count = m[3].length;
- type_inst.behs_count = m[4];
- type_inst.fx_count = m[5];
- type_inst.sid = m[11];
- if (type_inst.is_family)
- {
- type_inst.members = []; // types in this family
- type_inst.family_index = this.family_count++;
- type_inst.families = null;
- }
- else
- {
- type_inst.members = null;
- type_inst.family_index = -1;
- type_inst.families = []; // families this type belongs to
- }
- type_inst.family_var_map = null;
- type_inst.family_beh_map = null;
- type_inst.family_fx_map = null;
- type_inst.is_contained = false;
- type_inst.container = null;
- if (m[6])
- {
- type_inst.texture_file = m[6][0];
- type_inst.texture_filesize = m[6][1];
- type_inst.texture_pixelformat = m[6][2];
- }
- else
- {
- type_inst.texture_file = null;
- type_inst.texture_filesize = 0;
- type_inst.texture_pixelformat = 0; // rgba8
- }
- if (m[7])
- {
- type_inst.animations = m[7];
- }
- else
- {
- type_inst.animations = null;
- }
- type_inst.index = i; // save index in to types array in type
- type_inst.instances = []; // all instances of this type
- type_inst.deadCache = []; // destroyed instances to recycle next create
- type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL
- type_inst.cur_sol = 0;
- type_inst.default_instance = null;
- type_inst.default_layerindex = 0;
- type_inst.stale_iids = true;
- type_inst.updateIIDs = cr.type_updateIIDs;
- type_inst.getFirstPicked = cr.type_getFirstPicked;
- type_inst.getPairedInstance = cr.type_getPairedInstance;
- type_inst.getCurrentSol = cr.type_getCurrentSol;
- type_inst.pushCleanSol = cr.type_pushCleanSol;
- type_inst.pushCopySol = cr.type_pushCopySol;
- type_inst.popSol = cr.type_popSol;
- type_inst.getBehaviorByName = cr.type_getBehaviorByName;
- type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName;
- type_inst.getEffectIndexByName = cr.type_getEffectIndexByName;
- type_inst.applySolToContainer = cr.type_applySolToContainer;
- type_inst.getInstanceByIID = cr.type_getInstanceByIID;
- type_inst.collision_grid = new cr.SparseGrid(this.original_width, this.original_height);
- type_inst.any_cell_changed = true;
- type_inst.any_instance_parallaxed = false;
- type_inst.extra = {};
- type_inst.toString = cr.type_toString;
- type_inst.behaviors = [];
- for (j = 0, lenj = m[8].length; j < lenj; j++)
- {
- b = m[8][j];
- var behavior_ctor = this.GetObjectReference(b[1]);
- var behavior_plugin = null;
- for (k = 0, lenk = this.behaviors.length; k < lenk; k++)
- {
- if (this.behaviors[k] instanceof behavior_ctor)
- {
- behavior_plugin = this.behaviors[k];
- break;
- }
- }
- if (!behavior_plugin)
- {
- behavior_plugin = new behavior_ctor(this);
- behavior_plugin.my_types = []; // types using this behavior
- behavior_plugin.my_instances = new cr.ObjectSet(); // instances of this behavior
- if (behavior_plugin.onCreate)
- behavior_plugin.onCreate();
- cr.seal(behavior_plugin);
- this.behaviors.push(behavior_plugin);
- if (cr.behaviors.solid && behavior_plugin instanceof cr.behaviors.solid)
- this.solidBehavior = behavior_plugin;
- if (cr.behaviors.jumpthru && behavior_plugin instanceof cr.behaviors.jumpthru)
- this.jumpthruBehavior = behavior_plugin;
- if (cr.behaviors.shadowcaster && behavior_plugin instanceof cr.behaviors.shadowcaster)
- this.shadowcasterBehavior = behavior_plugin;
- }
- if (behavior_plugin.my_types.indexOf(type_inst) === -1)
- behavior_plugin.my_types.push(type_inst);
- var behavior_type = new behavior_plugin.Type(behavior_plugin, type_inst);
- behavior_type.name = b[0];
- behavior_type.sid = b[2];
- behavior_type.onCreate();
- cr.seal(behavior_type);
- type_inst.behaviors.push(behavior_type);
- }
- type_inst.global = m[9];
- type_inst.isOnLoaderLayout = m[10];
- type_inst.effect_types = [];
- for (j = 0, lenj = m[12].length; j < lenj; j++)
- {
- type_inst.effect_types.push({
- id: m[12][j][0],
- name: m[12][j][1],
- shaderindex: -1,
- preservesOpaqueness: false,
- active: true,
- index: j
- });
- }
- type_inst.tile_poly_data = m[13];
- if (!this.uses_loader_layout || type_inst.is_family || type_inst.isOnLoaderLayout || !plugin.is_world)
- {
- type_inst.onCreate();
- cr.seal(type_inst);
- }
- if (type_inst.name)
- this.types[type_inst.name] = type_inst;
- this.types_by_index.push(type_inst);
- if (plugin.singleglobal)
- {
- var instance = new plugin.Instance(type_inst);
- instance.uid = this.next_uid++;
- instance.puid = this.next_puid++;
- instance.iid = 0;
- instance.get_iid = cr.inst_get_iid;
- instance.toString = cr.inst_toString;
- instance.properties = m[14];
- instance.onCreate();
- cr.seal(instance);
- type_inst.instances.push(instance);
- this.objectsByUid[instance.uid.toString()] = instance;
- }
- }
- for (i = 0, len = pm[4].length; i < len; i++)
- {
- var familydata = pm[4][i];
- var familytype = this.types_by_index[familydata[0]];
- var familymember;
- for (j = 1, lenj = familydata.length; j < lenj; j++)
- {
- familymember = this.types_by_index[familydata[j]];
- familymember.families.push(familytype);
- familytype.members.push(familymember);
- }
- }
- for (i = 0, len = pm[28].length; i < len; i++)
- {
- var containerdata = pm[28][i];
- var containertypes = [];
- for (j = 0, lenj = containerdata.length; j < lenj; j++)
- containertypes.push(this.types_by_index[containerdata[j]]);
- for (j = 0, lenj = containertypes.length; j < lenj; j++)
- {
- containertypes[j].is_contained = true;
- containertypes[j].container = containertypes;
- }
- }
- if (this.family_count > 0)
- {
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- if (t.is_family || !t.families.length)
- continue;
- t.family_var_map = new Array(this.family_count);
- t.family_beh_map = new Array(this.family_count);
- t.family_fx_map = new Array(this.family_count);
- var all_fx = [];
- var varsum = 0;
- var behsum = 0;
- var fxsum = 0;
- for (j = 0, lenj = t.families.length; j < lenj; j++)
- {
- f = t.families[j];
- t.family_var_map[f.family_index] = varsum;
- varsum += f.vars_count;
- t.family_beh_map[f.family_index] = behsum;
- behsum += f.behs_count;
- t.family_fx_map[f.family_index] = fxsum;
- fxsum += f.fx_count;
- for (k = 0, lenk = f.effect_types.length; k < lenk; k++)
- all_fx.push(cr.shallowCopy({}, f.effect_types[k]));
- }
- t.effect_types = all_fx.concat(t.effect_types);
- for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
- t.effect_types[j].index = j;
- }
- }
- for (i = 0, len = pm[5].length; i < len; i++)
- {
- m = pm[5][i];
- var layout = new cr.layout(this, m);
- cr.seal(layout);
- this.layouts[layout.name] = layout;
- this.layouts_by_index.push(layout);
- }
- for (i = 0, len = pm[6].length; i < len; i++)
- {
- m = pm[6][i];
- var sheet = new cr.eventsheet(this, m);
- cr.seal(sheet);
- this.eventsheets[sheet.name] = sheet;
- this.eventsheets_by_index.push(sheet);
- }
- for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
- this.eventsheets_by_index[i].postInit();
- for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
- this.eventsheets_by_index[i].updateDeepIncludes();
- for (i = 0, len = this.triggers_to_postinit.length; i < len; i++)
- this.triggers_to_postinit[i].postInit();
- cr.clearArray(this.triggers_to_postinit)
- this.audio_to_preload = pm[7];
- this.files_subfolder = pm[8];
- this.pixel_rounding = pm[9];
- this.aspect_scale = 1.0;
- this.enableWebGL = pm[13];
- this.linearSampling = pm[14];
- this.clearBackground = pm[15];
- this.versionstr = pm[16];
- this.useHighDpi = pm[17];
- this.orientations = pm[20]; // 0 = any, 1 = portrait, 2 = landscape
- this.autoLockOrientation = (this.orientations > 0);
- this.pauseOnBlur = pm[22];
- this.wantFullscreenScalingQuality = pm[23]; // false = low quality, true = high quality
- this.fullscreenScalingQuality = this.wantFullscreenScalingQuality;
- this.downscalingQuality = pm[24]; // 0 = low (mips off), 1 = medium (mips on, dense spritesheet), 2 = high (mips on, sparse spritesheet)
- this.preloadSounds = pm[25]; // 0 = no, 1 = yes
- this.projectName = pm[26];
- this.enableFrontToBack = pm[27] && !this.isIE; // front-to-back renderer disabled in IE (but not Edge)
- this.start_time = Date.now();
- cr.clearArray(this.objectRefTable);
- this.initRendererAndLoader();
- };
- var anyImageHadError = false;
- var MAX_PARALLEL_IMAGE_LOADS = 100;
- var currentlyActiveImageLoads = 0;
- var imageLoadQueue = []; // array of [img, srcToSet]
- Runtime.prototype.queueImageLoad = function (img_, src_)
- {
- var self = this;
- var doneFunc = function ()
- {
- currentlyActiveImageLoads--;
- self.maybeLoadNextImages();
- };
- img_.addEventListener("load", doneFunc);
- img_.addEventListener("error", doneFunc);
- imageLoadQueue.push([img_, src_]);
- this.maybeLoadNextImages();
- };
- Runtime.prototype.maybeLoadNextImages = function ()
- {
- var next;
- while (imageLoadQueue.length && currentlyActiveImageLoads < MAX_PARALLEL_IMAGE_LOADS)
- {
- currentlyActiveImageLoads++;
- next = imageLoadQueue.shift();
- this.setImageSrc(next[0], next[1]);
- }
- };
- Runtime.prototype.waitForImageLoad = function (img_, src_)
- {
- img_["cocoonLazyLoad"] = true;
- img_.onerror = function (e)
- {
- img_.c2error = true;
- anyImageHadError = true;
- if (console && console.error)
- console.error("Error loading image '" + img_.src + "': ", e);
- };
- if (this.isEjecta)
- {
- img_.src = src_;
- }
- else if (!img_.src)
- {
- if (typeof XAPKReader !== "undefined")
- {
- XAPKReader.get(src_, function (expanded_url)
- {
- img_.src = expanded_url;
- }, function (e)
- {
- img_.c2error = true;
- anyImageHadError = true;
- if (console && console.error)
- console.error("Error extracting image '" + src_ + "' from expansion file: ", e);
- });
- }
- else
- {
- img_.crossOrigin = "anonymous"; // required for Arcade sandbox compatibility
- this.queueImageLoad(img_, src_); // use a queue to avoid requesting all images simultaneously
- }
- }
- this.wait_for_textures.push(img_);
- };
- Runtime.prototype.findWaitingTexture = function (src_)
- {
- var i, len;
- for (i = 0, len = this.wait_for_textures.length; i < len; i++)
- {
- if (this.wait_for_textures[i].cr_src === src_)
- return this.wait_for_textures[i];
- }
- return null;
- };
- var audio_preload_totalsize = 0;
- var audio_preload_started = false;
- Runtime.prototype.getready = function ()
- {
- if (!this.audioInstance)
- return;
- audio_preload_totalsize = this.audioInstance.setPreloadList(this.audio_to_preload);
- };
- Runtime.prototype.areAllTexturesAndSoundsLoaded = function ()
- {
- var totalsize = audio_preload_totalsize;
- var completedsize = 0;
- var audiocompletedsize = 0;
- var ret = true;
- var i, len, img;
- for (i = 0, len = this.wait_for_textures.length; i < len; i++)
- {
- img = this.wait_for_textures[i];
- var filesize = img.cr_filesize;
- if (!filesize || filesize <= 0)
- filesize = 50000;
- totalsize += filesize;
- if (!!img.src && (img.complete || img["loaded"]) && !img.c2error)
- completedsize += filesize;
- else
- ret = false; // not all textures loaded
- }
- if (ret && this.preloadSounds && this.audioInstance)
- {
- if (!audio_preload_started)
- {
- this.audioInstance.startPreloads();
- audio_preload_started = true;
- }
- audiocompletedsize = this.audioInstance.getPreloadedSize();
- completedsize += audiocompletedsize;
- if (audiocompletedsize < audio_preload_totalsize)
- ret = false; // not done yet
- }
- if (totalsize == 0)
- this.progress = 1; // indicate to C2 splash loader that it can finish now
- else
- this.progress = (completedsize / totalsize);
- return ret;
- };
- var isC2SplashDone = false;
- Runtime.prototype.go = function ()
- {
- if (!this.ctx && !this.glwrap)
- return;
- var ctx = this.ctx || this.overlay_ctx;
- if (this.overlay_canvas)
- this.positionOverlayCanvas();
- var curwidth = window.innerWidth;
- var curheight = window.innerHeight;
- if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
- {
- this["setSize"](curwidth, curheight);
- }
- this.progress = 0;
- this.last_progress = -1;
- var self = this;
- if (this.areAllTexturesAndSoundsLoaded() && (this.loaderstyle !== 4 || isC2SplashDone))
- {
- this.go_loading_finished();
- }
- else
- {
- var ms_elapsed = Date.now() - this.start_time;
- if (ctx)
- {
- var overlay_width = this.width;
- var overlay_height = this.height;
- var dpr = this.devicePixelRatio;
- if (this.loaderstyle < 3 && (this.isCocoonJs || (ms_elapsed >= 500 && this.last_progress != this.progress)))
- {
- ctx.clearRect(0, 0, overlay_width, overlay_height);
- var mx = overlay_width / 2;
- var my = overlay_height / 2;
- var haslogo = (this.loaderstyle === 0 && this.loaderlogos.logo.complete);
- var hlw = 40 * dpr;
- var hlh = 0;
- var logowidth = 80 * dpr;
- var logoheight;
- if (haslogo)
- {
- var loaderLogoImage = this.loaderlogos.logo;
- logowidth = loaderLogoImage.width * dpr;
- logoheight = loaderLogoImage.height * dpr;
- hlw = logowidth / 2;
- hlh = logoheight / 2;
- ctx.drawImage(loaderLogoImage, cr.floor(mx - hlw), cr.floor(my - hlh), logowidth, logoheight);
- }
- if (this.loaderstyle <= 1)
- {
- my += hlh + (haslogo ? 12 * dpr : 0);
- mx -= hlw;
- mx = cr.floor(mx) + 0.5;
- my = cr.floor(my) + 0.5;
- ctx.fillStyle = anyImageHadError ? "red" : "DodgerBlue";
- ctx.fillRect(mx, my, Math.floor(logowidth * this.progress), 6 * dpr);
- ctx.strokeStyle = "black";
- ctx.strokeRect(mx, my, logowidth, 6 * dpr);
- ctx.strokeStyle = "white";
- ctx.strokeRect(mx - 1 * dpr, my - 1 * dpr, logowidth + 2 * dpr, 8 * dpr);
- }
- else if (this.loaderstyle === 2)
- {
- ctx.font = (this.isEjecta ? "12pt ArialMT" : "12pt Arial");
- ctx.fillStyle = anyImageHadError ? "#f00" : "#999";
- ctx.textBaseLine = "middle";
- var percent_text = Math.round(this.progress * 100) + "%";
- var text_dim = ctx.measureText ? ctx.measureText(percent_text) : null;
- var text_width = text_dim ? text_dim.width : 0;
- ctx.fillText(percent_text, mx - (text_width / 2), my);
- }
- this.last_progress = this.progress;
- }
- else if (this.loaderstyle === 4)
- {
- this.draw_c2_splash_loader(ctx);
- if (raf)
- raf(function() { self.go(); });
- else
- setTimeout(function() { self.go(); }, 16);
- return;
- }
- }
- setTimeout(function() { self.go(); }, (this.isCocoonJs ? 10 : 100));
- }
- };
- var splashStartTime = -1;
- var splashFadeInDuration = 300;
- var splashFadeOutDuration = 300;
- var splashAfterFadeOutWait = (typeof cr_is_preview === "undefined" ? 200 : 0);
- var splashIsFadeIn = true;
- var splashIsFadeOut = false;
- var splashFadeInFinish = 0;
- var splashFadeOutStart = 0;
- var splashMinDisplayTime = (typeof cr_is_preview === "undefined" ? 3000 : 0);
- var renderViaCanvas = null;
- var renderViaCtx = null;
- var splashFrameNumber = 0;
- function maybeCreateRenderViaCanvas(w, h)
- {
- if (!renderViaCanvas || renderViaCanvas.width !== w || renderViaCanvas.height !== h)
- {
- renderViaCanvas = document.createElement("canvas");
- renderViaCanvas.width = w;
- renderViaCanvas.height = h;
- renderViaCtx = renderViaCanvas.getContext("2d");
- }
- };
- function mipImage(arr, size)
- {
- if (size <= 128)
- return arr[3];
- else if (size <= 256)
- return arr[2];
- else if (size <= 512)
- return arr[1];
- else
- return arr[0];
- };
- Runtime.prototype.draw_c2_splash_loader = function(ctx)
- {
- if (isC2SplashDone)
- return;
- var w = Math.ceil(this.width);
- var h = Math.ceil(this.height);
- var dpr = this.devicePixelRatio;
- var logoimages = this.loaderlogos.logo;
- var poweredimages = this.loaderlogos.powered;
- var websiteimages = this.loaderlogos.website;
- for (var i = 0; i < 4; ++i)
- {
- if (!logoimages[i].complete || !poweredimages[i].complete || !websiteimages[i].complete)
- return;
- }
- if (splashFrameNumber === 0)
- splashStartTime = Date.now();
- var nowTime = Date.now();
- var isRenderingVia = false;
- var renderToCtx = ctx;
- var drawW, drawH;
- if (splashIsFadeIn || splashIsFadeOut)
- {
- ctx.clearRect(0, 0, w, h);
- maybeCreateRenderViaCanvas(w, h);
- renderToCtx = renderViaCtx;
- isRenderingVia = true;
- if (splashIsFadeIn && splashFrameNumber === 1)
- splashStartTime = Date.now();
- }
- else
- {
- ctx.globalAlpha = 1;
- }
- renderToCtx.fillStyle = "#333333";
- renderToCtx.fillRect(0, 0, w, h);
- if (this.cssHeight > 256)
- {
- drawW = cr.clamp(h * 0.22, 105, w * 0.6);
- drawH = drawW * 0.25;
- renderToCtx.drawImage(mipImage(poweredimages, drawW), w * 0.5 - drawW/2, h * 0.2 - drawH/2, drawW, drawH);
- drawW = Math.min(h * 0.395, w * 0.95);
- drawH = drawW;
- renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.485 - drawH/2, drawW, drawH);
- drawW = cr.clamp(h * 0.22, 105, w * 0.6);
- drawH = drawW * 0.25;
- renderToCtx.drawImage(mipImage(websiteimages, drawW), w * 0.5 - drawW/2, h * 0.868 - drawH/2, drawW, drawH);
- renderToCtx.fillStyle = "#3C3C3C";
- drawW = w;
- drawH = Math.max(h * 0.005, 2);
- renderToCtx.fillRect(0, h * 0.8 - drawH/2, drawW, drawH);
- renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
- drawW = w * this.progress;
- renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.8 - drawH/2, drawW, drawH);
- }
- else
- {
- drawW = h * 0.55;
- drawH = drawW;
- renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.45 - drawH/2, drawW, drawH);
- renderToCtx.fillStyle = "#3C3C3C";
- drawW = w;
- drawH = Math.max(h * 0.005, 2);
- renderToCtx.fillRect(0, h * 0.85 - drawH/2, drawW, drawH);
- renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
- drawW = w * this.progress;
- renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.85 - drawH/2, drawW, drawH);
- }
- if (isRenderingVia)
- {
- if (splashIsFadeIn)
- {
- if (splashFrameNumber === 0)
- ctx.globalAlpha = 0;
- else
- ctx.globalAlpha = Math.min((nowTime - splashStartTime) / splashFadeInDuration, 1);
- }
- else if (splashIsFadeOut)
- {
- ctx.globalAlpha = Math.max(1 - (nowTime - splashFadeOutStart) / splashFadeOutDuration, 0);
- }
- ctx.drawImage(renderViaCanvas, 0, 0, w, h);
- }
- if (splashIsFadeIn && nowTime - splashStartTime >= splashFadeInDuration && splashFrameNumber >= 2)
- {
- splashIsFadeIn = false;
- splashFadeInFinish = nowTime;
- }
- if (!splashIsFadeIn && nowTime - splashFadeInFinish >= splashMinDisplayTime && !splashIsFadeOut && this.progress >= 1)
- {
- splashIsFadeOut = true;
- splashFadeOutStart = nowTime;
- }
- if ((splashIsFadeOut && nowTime - splashFadeOutStart >= splashFadeOutDuration + splashAfterFadeOutWait) ||
- (typeof cr_is_preview !== "undefined" && this.progress >= 1 && Date.now() - splashStartTime < 500))
- {
- isC2SplashDone = true;
- splashIsFadeIn = false;
- splashIsFadeOut = false;
- renderViaCanvas = null;
- renderViaCtx = null;
- this.loaderlogos = null;
- }
- ++splashFrameNumber;
- };
- Runtime.prototype.go_loading_finished = function ()
- {
- if (this.overlay_canvas)
- {
- this.canvas.parentNode.removeChild(this.overlay_canvas);
- this.overlay_ctx = null;
- this.overlay_canvas = null;
- }
- this.start_time = Date.now();
- this.last_fps_time = cr.performance_now(); // for counting framerate
- var i, len, t;
- if (this.uses_loader_layout)
- {
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- if (!t.is_family && !t.isOnLoaderLayout && t.plugin.is_world)
- {
- t.onCreate();
- cr.seal(t);
- }
- }
- }
- else
- this.isloading = false;
- for (i = 0, len = this.layouts_by_index.length; i < len; i++)
- {
- this.layouts_by_index[i].createGlobalNonWorlds();
- }
- if (this.fullscreen_mode >= 2)
- {
- var orig_aspect = this.original_width / this.original_height;
- var cur_aspect = this.width / this.height;
- if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
- this.aspect_scale = this.height / this.original_height;
- else
- this.aspect_scale = this.width / this.original_width;
- }
- if (this.first_layout)
- this.layouts[this.first_layout].startRunning();
- else
- this.layouts_by_index[0].startRunning();
-;
- if (!this.uses_loader_layout)
- {
- this.loadingprogress = 1;
- this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
- if (window["C2_RegisterSW"]) // note not all platforms use SW
- window["C2_RegisterSW"]();
- }
- if (navigator["splashscreen"] && navigator["splashscreen"]["hide"])
- navigator["splashscreen"]["hide"]();
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- t = this.types_by_index[i];
- if (t.onAppBegin)
- t.onAppBegin();
- }
- if (document["hidden"] || document["webkitHidden"] || document["mozHidden"] || document["msHidden"])
- {
- window["cr_setSuspended"](true); // stop rendering
- }
- else
- {
- this.tick(false);
- }
- if (this.isDirectCanvas)
- AppMobi["webview"]["execute"]("onGameReady();");
- };
- Runtime.prototype.tick = function (background_wake, timestamp, debug_step)
- {
- if (!this.running_layout)
- return;
- var nowtime = cr.performance_now();
- var logic_start = nowtime;
- if (!debug_step && this.isSuspended && !background_wake)
- return;
- if (!background_wake)
- {
- if (raf)
- this.raf_id = raf(this.tickFunc);
- else
- {
- this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16);
- }
- }
- var raf_time = timestamp || nowtime;
- var fsmode = this.fullscreen_mode;
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"]) && !this.isCordova;
- if ((isfullscreen || this.isNodeFullscreen) && this.fullscreen_scaling > 0)
- fsmode = this.fullscreen_scaling;
- if (fsmode > 0) // r222: experimentally enabling this workaround for all platforms
- {
- var curwidth = window.innerWidth;
- var curheight = window.innerHeight;
- if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
- {
- this["setSize"](curwidth, curheight);
- }
- }
- if (!this.isDomFree)
- {
- if (isfullscreen)
- {
- if (!this.firstInFullscreen)
- this.firstInFullscreen = true;
- }
- else
- {
- if (this.firstInFullscreen)
- {
- this.firstInFullscreen = false;
- if (this.fullscreen_mode === 0)
- {
- this["setSize"](Math.round(this.oldWidth / this.devicePixelRatio), Math.round(this.oldHeight / this.devicePixelRatio), true);
- }
- }
- else
- {
- this.oldWidth = this.width;
- this.oldHeight = this.height;
- }
- }
- }
- if (this.isloading)
- {
- var done = this.areAllTexturesAndSoundsLoaded(); // updates this.progress
- this.loadingprogress = this.progress;
- if (done)
- {
- this.isloading = false;
- this.progress = 1;
- this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
- if (window["C2_RegisterSW"])
- window["C2_RegisterSW"]();
- }
- }
- this.logic(raf_time);
- if ((this.redraw || this.isCocoonJs) && !this.is_WebGL_context_lost && !this.suspendDrawing && !background_wake)
- {
- this.redraw = false;
- if (this.glwrap)
- this.drawGL();
- else
- this.draw();
- if (this.snapshotCanvas)
- {
- if (this.canvas && this.canvas.toDataURL)
- {
- this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]);
- if (window["cr_onSnapshot"])
- window["cr_onSnapshot"](this.snapshotData);
- this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null);
- }
- this.snapshotCanvas = null;
- }
- }
- if (!this.hit_breakpoint)
- {
- this.tickcount++;
- this.tickcount_nosave++;
- this.execcount++;
- this.framecount++;
- }
- this.logictime += cr.performance_now() - logic_start;
- };
- Runtime.prototype.logic = function (cur_time)
- {
- var i, leni, j, lenj, k, lenk, type, inst, binst;
- if (cur_time - this.last_fps_time >= 1000) // every 1 second
- {
- this.last_fps_time += 1000;
- if (cur_time - this.last_fps_time >= 1000)
- this.last_fps_time = cur_time;
- this.fps = this.framecount;
- this.framecount = 0;
- this.cpuutilisation = this.logictime;
- this.logictime = 0;
- }
- var wallDt = 0;
- if (this.last_tick_time !== 0)
- {
- var ms_diff = cur_time - this.last_tick_time;
- if (ms_diff < 0)
- ms_diff = 0;
- wallDt = ms_diff / 1000.0; // dt measured in seconds
- this.dt1 = wallDt;
- if (this.dt1 > 0.5)
- this.dt1 = 0;
- else if (this.dt1 > 1 / this.minimumFramerate)
- this.dt1 = 1 / this.minimumFramerate;
- }
- this.last_tick_time = cur_time;
- this.dt = this.dt1 * this.timescale;
- this.kahanTime.add(this.dt);
- this.wallTime.add(wallDt); // prevent min/max framerate affecting wall clock
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
- if (this.fullscreen_mode >= 2 /* scale */ || (isfullscreen && this.fullscreen_scaling > 0))
- {
- var orig_aspect = this.original_width / this.original_height;
- var cur_aspect = this.width / this.height;
- var mode = this.fullscreen_mode;
- if (isfullscreen && this.fullscreen_scaling > 0)
- mode = this.fullscreen_scaling;
- if ((mode !== 2 && cur_aspect > orig_aspect) || (mode === 2 && cur_aspect < orig_aspect))
- {
- this.aspect_scale = this.height / this.original_height;
- }
- else
- {
- this.aspect_scale = this.width / this.original_width;
- }
- if (this.running_layout)
- {
- this.running_layout.scrollToX(this.running_layout.scrollX);
- this.running_layout.scrollToY(this.running_layout.scrollY);
- }
- }
- else
- this.aspect_scale = (this.isRetina ? this.devicePixelRatio : 1);
- this.ClearDeathRow();
- this.isInOnDestroy++;
- this.system.runWaits(); // prevent instance list changing
- this.isInOnDestroy--;
- this.ClearDeathRow(); // allow instance list changing
- this.isInOnDestroy++;
- var tickarr = this.objects_to_pretick.valuesRef();
- for (i = 0, leni = tickarr.length; i < leni; i++)
- tickarr[i].pretick();
- for (i = 0, leni = this.types_by_index.length; i < leni; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family || (!type.behaviors.length && !type.families.length))
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- inst.behavior_insts[k].tick();
- }
- }
- }
- for (i = 0, leni = this.types_by_index.length; i < leni; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family || (!type.behaviors.length && !type.families.length))
- continue; // type doesn't have any behaviors
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- binst = inst.behavior_insts[k];
- if (binst.posttick)
- binst.posttick();
- }
- }
- }
- tickarr = this.objects_to_tick.valuesRef();
- for (i = 0, leni = tickarr.length; i < leni; i++)
- tickarr[i].tick();
- this.isInOnDestroy--; // end preventing instance lists from being changed
- this.handleSaveLoad(); // save/load now if queued
- i = 0;
- while (this.changelayout && i++ < 10)
- {
- this.doChangeLayout(this.changelayout);
- }
- for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
- this.eventsheets_by_index[i].hasRun = false;
- if (this.running_layout.event_sheet)
- this.running_layout.event_sheet.run();
- cr.clearArray(this.registered_collisions);
- this.layout_first_tick = false;
- this.isInOnDestroy++; // prevent instance lists from being changed
- for (i = 0, leni = this.types_by_index.length; i < leni; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family || (!type.behaviors.length && !type.families.length))
- continue; // type doesn't have any behaviors
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- var inst = type.instances[j];
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- binst = inst.behavior_insts[k];
- if (binst.tick2)
- binst.tick2();
- }
- }
- }
- tickarr = this.objects_to_tick2.valuesRef();
- for (i = 0, leni = tickarr.length; i < leni; i++)
- tickarr[i].tick2();
- this.isInOnDestroy--; // end preventing instance lists from being changed
- };
- Runtime.prototype.onWindowBlur = function ()
- {
- var i, leni, j, lenj, k, lenk, type, inst, binst;
- for (i = 0, leni = this.types_by_index.length; i < leni; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family)
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- if (inst.onWindowBlur)
- inst.onWindowBlur();
- if (!inst.behavior_insts)
- continue; // single-globals don't have behavior_insts
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- binst = inst.behavior_insts[k];
- if (binst.onWindowBlur)
- binst.onWindowBlur();
- }
- }
- }
- };
- Runtime.prototype.doChangeLayout = function (changeToLayout)
- {
- var prev_layout = this.running_layout;
- this.running_layout.stopRunning();
- var i, len, j, lenj, k, lenk, type, inst, binst;
- if (this.glwrap)
- {
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family)
- continue;
- if (type.unloadTextures && (!type.global || type.instances.length === 0) && changeToLayout.initial_types.indexOf(type) === -1)
- {
- type.unloadTextures();
- }
- }
- }
- if (prev_layout == changeToLayout)
- cr.clearArray(this.system.waits);
- cr.clearArray(this.registered_collisions);
- this.runLayoutChangeMethods(true);
- changeToLayout.startRunning();
- this.runLayoutChangeMethods(false);
- this.redraw = true;
- this.layout_first_tick = true;
- this.ClearDeathRow();
- };
- Runtime.prototype.runLayoutChangeMethods = function (isBeforeChange)
- {
- var i, len, beh, type, j, lenj, inst, k, lenk, binst;
- for (i = 0, len = this.behaviors.length; i < len; i++)
- {
- beh = this.behaviors[i];
- if (isBeforeChange)
- {
- if (beh.onBeforeLayoutChange)
- beh.onBeforeLayoutChange();
- }
- else
- {
- if (beh.onLayoutChange)
- beh.onLayoutChange();
- }
- }
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- type = this.types_by_index[i];
- if (!type.global && !type.plugin.singleglobal)
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- if (isBeforeChange)
- {
- if (inst.onBeforeLayoutChange)
- inst.onBeforeLayoutChange();
- }
- else
- {
- if (inst.onLayoutChange)
- inst.onLayoutChange();
- }
- if (inst.behavior_insts)
- {
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- binst = inst.behavior_insts[k];
- if (isBeforeChange)
- {
- if (binst.onBeforeLayoutChange)
- binst.onBeforeLayoutChange();
- }
- else
- {
- if (binst.onLayoutChange)
- binst.onLayoutChange();
- }
- }
- }
- }
- }
- };
- Runtime.prototype.pretickMe = function (inst)
- {
- this.objects_to_pretick.add(inst);
- };
- Runtime.prototype.unpretickMe = function (inst)
- {
- this.objects_to_pretick.remove(inst);
- };
- Runtime.prototype.tickMe = function (inst)
- {
- this.objects_to_tick.add(inst);
- };
- Runtime.prototype.untickMe = function (inst)
- {
- this.objects_to_tick.remove(inst);
- };
- Runtime.prototype.tick2Me = function (inst)
- {
- this.objects_to_tick2.add(inst);
- };
- Runtime.prototype.untick2Me = function (inst)
- {
- this.objects_to_tick2.remove(inst);
- };
- Runtime.prototype.getDt = function (inst)
- {
- if (!inst || inst.my_timescale === -1.0)
- return this.dt;
- return this.dt1 * inst.my_timescale;
- };
- Runtime.prototype.draw = function ()
- {
- this.running_layout.draw(this.ctx);
- if (this.isDirectCanvas)
- this.ctx["present"]();
- };
- Runtime.prototype.drawGL = function ()
- {
- if (this.enableFrontToBack)
- {
- this.earlyz_index = 1; // start from front, 1-based to avoid exactly equalling near plane Z value
- this.running_layout.drawGL_earlyZPass(this.glwrap);
- }
- this.running_layout.drawGL(this.glwrap);
- this.glwrap.present();
- };
- Runtime.prototype.addDestroyCallback = function (f)
- {
- if (f)
- this.destroycallbacks.push(f);
- };
- Runtime.prototype.removeDestroyCallback = function (f)
- {
- cr.arrayFindRemove(this.destroycallbacks, f);
- };
- Runtime.prototype.getObjectByUID = function (uid_)
- {
-;
- var uidstr = uid_.toString();
- if (this.objectsByUid.hasOwnProperty(uidstr))
- return this.objectsByUid[uidstr];
- else
- return null;
- };
- var objectset_cache = [];
- function alloc_objectset()
- {
- if (objectset_cache.length)
- return objectset_cache.pop();
- else
- return new cr.ObjectSet();
- };
- function free_objectset(s)
- {
- s.clear();
- objectset_cache.push(s);
- };
- Runtime.prototype.DestroyInstance = function (inst)
- {
- var i, len;
- var type = inst.type;
- var typename = type.name;
- var has_typename = this.deathRow.hasOwnProperty(typename);
- var obj_set = null;
- if (has_typename)
- {
- obj_set = this.deathRow[typename];
- if (obj_set.contains(inst))
- return; // already had DestroyInstance called
- }
- else
- {
- obj_set = alloc_objectset();
- this.deathRow[typename] = obj_set;
- }
- obj_set.add(inst);
- this.hasPendingInstances = true;
- if (inst.is_contained)
- {
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- this.DestroyInstance(inst.siblings[i]);
- }
- }
- if (this.isInClearDeathRow)
- obj_set.values_cache.push(inst);
- if (!this.isEndingLayout)
- {
- this.isInOnDestroy++; // support recursion
- this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnDestroyed, inst);
- this.isInOnDestroy--;
- }
- };
- Runtime.prototype.ClearDeathRow = function ()
- {
- if (!this.hasPendingInstances)
- return;
- var inst, type, instances;
- var i, j, leni, lenj, obj_set;
- this.isInClearDeathRow = true;
- for (i = 0, leni = this.createRow.length; i < leni; ++i)
- {
- inst = this.createRow[i];
- type = inst.type;
- type.instances.push(inst);
- for (j = 0, lenj = type.families.length; j < lenj; ++j)
- {
- type.families[j].instances.push(inst);
- type.families[j].stale_iids = true;
- }
- }
- cr.clearArray(this.createRow);
- this.IterateDeathRow(); // moved to separate function so for-in performance doesn't hobble entire function
- cr.wipe(this.deathRow); // all objectsets have already been recycled
- this.isInClearDeathRow = false;
- this.hasPendingInstances = false;
- };
- Runtime.prototype.IterateDeathRow = function ()
- {
- for (var p in this.deathRow)
- {
- if (this.deathRow.hasOwnProperty(p))
- {
- this.ClearDeathRowForType(this.deathRow[p]);
- }
- }
- };
- Runtime.prototype.ClearDeathRowForType = function (obj_set)
- {
- var arr = obj_set.valuesRef(); // get array of items from set
-;
- var type = arr[0].type;
-;
-;
- var i, len, j, lenj, w, f, layer_instances, inst;
- cr.arrayRemoveAllFromObjectSet(type.instances, obj_set);
- type.stale_iids = true;
- if (type.instances.length === 0)
- type.any_instance_parallaxed = false;
- for (i = 0, len = type.families.length; i < len; ++i)
- {
- f = type.families[i];
- cr.arrayRemoveAllFromObjectSet(f.instances, obj_set);
- f.stale_iids = true;
- }
- for (i = 0, len = this.system.waits.length; i < len; ++i)
- {
- w = this.system.waits[i];
- if (w.sols.hasOwnProperty(type.index))
- cr.arrayRemoveAllFromObjectSet(w.sols[type.index].insts, obj_set);
- if (!type.is_family)
- {
- for (j = 0, lenj = type.families.length; j < lenj; ++j)
- {
- f = type.families[j];
- if (w.sols.hasOwnProperty(f.index))
- cr.arrayRemoveAllFromObjectSet(w.sols[f.index].insts, obj_set);
- }
- }
- }
- var first_layer = arr[0].layer;
- if (first_layer)
- {
- if (first_layer.useRenderCells)
- {
- layer_instances = first_layer.instances;
- for (i = 0, len = layer_instances.length; i < len; ++i)
- {
- inst = layer_instances[i];
- if (!obj_set.contains(inst))
- continue; // not destroying this instance
- inst.update_bbox();
- first_layer.render_grid.update(inst, inst.rendercells, null);
- inst.rendercells.set(0, 0, -1, -1);
- }
- }
- cr.arrayRemoveAllFromObjectSet(first_layer.instances, obj_set);
- first_layer.setZIndicesStaleFrom(0);
- }
- for (i = 0; i < arr.length; ++i) // check array length every time in case it changes
- {
- this.ClearDeathRowForSingleInstance(arr[i], type);
- }
- free_objectset(obj_set);
- this.redraw = true;
- };
- Runtime.prototype.ClearDeathRowForSingleInstance = function (inst, type)
- {
- var i, len, binst;
- for (i = 0, len = this.destroycallbacks.length; i < len; ++i)
- this.destroycallbacks[i](inst);
- if (inst.collcells)
- {
- type.collision_grid.update(inst, inst.collcells, null);
- }
- var layer = inst.layer;
- if (layer)
- {
- layer.removeFromInstanceList(inst, true); // remove from both instance list and render grid
- }
- if (inst.behavior_insts)
- {
- for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
- {
- binst = inst.behavior_insts[i];
- if (binst.onDestroy)
- binst.onDestroy();
- binst.behavior.my_instances.remove(inst);
- }
- }
- this.objects_to_pretick.remove(inst);
- this.objects_to_tick.remove(inst);
- this.objects_to_tick2.remove(inst);
- if (inst.onDestroy)
- inst.onDestroy();
- if (this.objectsByUid.hasOwnProperty(inst.uid.toString()))
- delete this.objectsByUid[inst.uid.toString()];
- this.objectcount--;
- if (type.deadCache.length < 100)
- type.deadCache.push(inst);
- };
- Runtime.prototype.createInstance = function (type, layer, sx, sy)
- {
- if (type.is_family)
- {
- var i = cr.floor(Math.random() * type.members.length);
- return this.createInstance(type.members[i], layer, sx, sy);
- }
- if (!type.default_instance)
- {
- return null;
- }
- return this.createInstanceFromInit(type.default_instance, layer, false, sx, sy, false);
- };
- var all_behaviors = [];
- Runtime.prototype.createInstanceFromInit = function (initial_inst, layer, is_startup_instance, sx, sy, skip_siblings)
- {
- var i, len, j, lenj, p, effect_fallback, x, y;
- if (!initial_inst)
- return null;
- var type = this.types_by_index[initial_inst[1]];
-;
-;
- var is_world = type.plugin.is_world;
-;
- if (this.isloading && is_world && !type.isOnLoaderLayout)
- return null;
- if (is_world && !this.glwrap && initial_inst[0][11] === 11)
- return null;
- var original_layer = layer;
- if (!is_world)
- layer = null;
- var inst;
- if (type.deadCache.length)
- {
- inst = type.deadCache.pop();
- inst.recycled = true;
- type.plugin.Instance.call(inst, type);
- }
- else
- {
- inst = new type.plugin.Instance(type);
- inst.recycled = false;
- }
- if (is_startup_instance && !skip_siblings && !this.objectsByUid.hasOwnProperty(initial_inst[2].toString()))
- inst.uid = initial_inst[2];
- else
- inst.uid = this.next_uid++;
- this.objectsByUid[inst.uid.toString()] = inst;
- inst.puid = this.next_puid++;
- inst.iid = type.instances.length;
- for (i = 0, len = this.createRow.length; i < len; ++i)
- {
- if (this.createRow[i].type === type)
- inst.iid++;
- }
- inst.get_iid = cr.inst_get_iid;
- inst.toString = cr.inst_toString;
- var initial_vars = initial_inst[3];
- if (inst.recycled)
- {
- cr.wipe(inst.extra);
- }
- else
- {
- inst.extra = {};
- if (typeof cr_is_preview !== "undefined")
- {
- inst.instance_var_names = [];
- inst.instance_var_names.length = initial_vars.length;
- for (i = 0, len = initial_vars.length; i < len; i++)
- inst.instance_var_names[i] = initial_vars[i][1];
- }
- inst.instance_vars = [];
- inst.instance_vars.length = initial_vars.length;
- }
- for (i = 0, len = initial_vars.length; i < len; i++)
- inst.instance_vars[i] = initial_vars[i][0];
- if (is_world)
- {
- var wm = initial_inst[0];
-;
- inst.x = cr.is_undefined(sx) ? wm[0] : sx;
- inst.y = cr.is_undefined(sy) ? wm[1] : sy;
- inst.z = wm[2];
- inst.width = wm[3];
- inst.height = wm[4];
- inst.depth = wm[5];
- inst.angle = wm[6];
- inst.opacity = wm[7];
- inst.hotspotX = wm[8];
- inst.hotspotY = wm[9];
- inst.blend_mode = wm[10];
- effect_fallback = wm[11];
- if (!this.glwrap && type.effect_types.length) // no WebGL renderer and shaders used
- inst.blend_mode = effect_fallback; // use fallback blend mode - destroy mode was handled above
- inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
- if (this.gl)
- cr.setGLBlend(inst, inst.blend_mode, this.gl);
- if (inst.recycled)
- {
- for (i = 0, len = wm[12].length; i < len; i++)
- {
- for (j = 0, lenj = wm[12][i].length; j < lenj; j++)
- inst.effect_params[i][j] = wm[12][i][j];
- }
- inst.bbox.set(0, 0, 0, 0);
- inst.collcells.set(0, 0, -1, -1);
- inst.rendercells.set(0, 0, -1, -1);
- inst.bquad.set_from_rect(inst.bbox);
- cr.clearArray(inst.bbox_changed_callbacks);
- }
- else
- {
- inst.effect_params = wm[12].slice(0);
- for (i = 0, len = inst.effect_params.length; i < len; i++)
- inst.effect_params[i] = wm[12][i].slice(0);
- inst.active_effect_types = [];
- inst.active_effect_flags = [];
- inst.active_effect_flags.length = type.effect_types.length;
- inst.bbox = new cr.rect(0, 0, 0, 0);
- inst.collcells = new cr.rect(0, 0, -1, -1);
- inst.rendercells = new cr.rect(0, 0, -1, -1);
- inst.bquad = new cr.quad();
- inst.bbox_changed_callbacks = [];
- inst.set_bbox_changed = cr.set_bbox_changed;
- inst.add_bbox_changed_callback = cr.add_bbox_changed_callback;
- inst.contains_pt = cr.inst_contains_pt;
- inst.update_bbox = cr.update_bbox;
- inst.update_render_cell = cr.update_render_cell;
- inst.update_collision_cell = cr.update_collision_cell;
- inst.get_zindex = cr.inst_get_zindex;
- }
- inst.tilemap_exists = false;
- inst.tilemap_width = 0;
- inst.tilemap_height = 0;
- inst.tilemap_data = null;
- if (wm.length === 14)
- {
- inst.tilemap_exists = true;
- inst.tilemap_width = wm[13][0];
- inst.tilemap_height = wm[13][1];
- inst.tilemap_data = wm[13][2];
- }
- for (i = 0, len = type.effect_types.length; i < len; i++)
- inst.active_effect_flags[i] = true;
- inst.shaders_preserve_opaqueness = true;
- inst.updateActiveEffects = cr.inst_updateActiveEffects;
- inst.updateActiveEffects();
- inst.uses_shaders = !!inst.active_effect_types.length;
- inst.bbox_changed = true;
- inst.cell_changed = true;
- type.any_cell_changed = true;
- inst.visible = true;
- inst.my_timescale = -1.0;
- inst.layer = layer;
- inst.zindex = layer.instances.length; // will be placed at top of current layer
- inst.earlyz_index = 0;
- if (typeof inst.collision_poly === "undefined")
- inst.collision_poly = null;
- inst.collisionsEnabled = true;
- this.redraw = true;
- }
- var initial_props, binst;
- cr.clearArray(all_behaviors);
- for (i = 0, len = type.families.length; i < len; i++)
- {
- all_behaviors.push.apply(all_behaviors, type.families[i].behaviors);
- }
- all_behaviors.push.apply(all_behaviors, type.behaviors);
- if (inst.recycled)
- {
- for (i = 0, len = all_behaviors.length; i < len; i++)
- {
- var btype = all_behaviors[i];
- binst = inst.behavior_insts[i];
- binst.recycled = true;
- btype.behavior.Instance.call(binst, btype, inst);
- initial_props = initial_inst[4][i];
- for (j = 0, lenj = initial_props.length; j < lenj; j++)
- binst.properties[j] = initial_props[j];
- binst.onCreate();
- btype.behavior.my_instances.add(inst);
- }
- }
- else
- {
- inst.behavior_insts = [];
- for (i = 0, len = all_behaviors.length; i < len; i++)
- {
- var btype = all_behaviors[i];
- var binst = new btype.behavior.Instance(btype, inst);
- binst.recycled = false;
- binst.properties = initial_inst[4][i].slice(0);
- binst.onCreate();
- cr.seal(binst);
- inst.behavior_insts.push(binst);
- btype.behavior.my_instances.add(inst);
- }
- }
- initial_props = initial_inst[5];
- if (inst.recycled)
- {
- for (i = 0, len = initial_props.length; i < len; i++)
- inst.properties[i] = initial_props[i];
- }
- else
- inst.properties = initial_props.slice(0);
- this.createRow.push(inst);
- this.hasPendingInstances = true;
- if (layer)
- {
-;
- layer.appendToInstanceList(inst, true);
- if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
- type.any_instance_parallaxed = true;
- }
- this.objectcount++;
- if (type.is_contained)
- {
- inst.is_contained = true;
- if (inst.recycled)
- cr.clearArray(inst.siblings);
- else
- inst.siblings = []; // note: should not include self in siblings
- if (!is_startup_instance && !skip_siblings) // layout links initial instances
- {
- for (i = 0, len = type.container.length; i < len; i++)
- {
- if (type.container[i] === type)
- continue;
- if (!type.container[i].default_instance)
- {
- return null;
- }
- inst.siblings.push(this.createInstanceFromInit(type.container[i].default_instance, original_layer, false, is_world ? inst.x : sx, is_world ? inst.y : sy, true));
- }
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- inst.siblings[i].siblings.push(inst);
- for (j = 0; j < len; j++)
- {
- if (i !== j)
- inst.siblings[i].siblings.push(inst.siblings[j]);
- }
- }
- }
- }
- else
- {
- inst.is_contained = false;
- inst.siblings = null;
- }
- inst.onCreate();
- if (!inst.recycled)
- cr.seal(inst);
- for (i = 0, len = inst.behavior_insts.length; i < len; i++)
- {
- if (inst.behavior_insts[i].postCreate)
- inst.behavior_insts[i].postCreate();
- }
- return inst;
- };
- Runtime.prototype.getLayerByName = function (layer_name)
- {
- var i, len;
- for (i = 0, len = this.running_layout.layers.length; i < len; i++)
- {
- var layer = this.running_layout.layers[i];
- if (cr.equals_nocase(layer.name, layer_name))
- return layer;
- }
- return null;
- };
- Runtime.prototype.getLayerByNumber = function (index)
- {
- index = cr.floor(index);
- if (index < 0)
- index = 0;
- if (index >= this.running_layout.layers.length)
- index = this.running_layout.layers.length - 1;
- return this.running_layout.layers[index];
- };
- Runtime.prototype.getLayer = function (l)
- {
- if (cr.is_number(l))
- return this.getLayerByNumber(l);
- else
- return this.getLayerByName(l.toString());
- };
- Runtime.prototype.clearSol = function (solModifiers)
- {
- var i, len;
- for (i = 0, len = solModifiers.length; i < len; i++)
- {
- solModifiers[i].getCurrentSol().select_all = true;
- }
- };
- Runtime.prototype.pushCleanSol = function (solModifiers)
- {
- var i, len;
- for (i = 0, len = solModifiers.length; i < len; i++)
- {
- solModifiers[i].pushCleanSol();
- }
- };
- Runtime.prototype.pushCopySol = function (solModifiers)
- {
- var i, len;
- for (i = 0, len = solModifiers.length; i < len; i++)
- {
- solModifiers[i].pushCopySol();
- }
- };
- Runtime.prototype.popSol = function (solModifiers)
- {
- var i, len;
- for (i = 0, len = solModifiers.length; i < len; i++)
- {
- solModifiers[i].popSol();
- }
- };
- Runtime.prototype.updateAllCells = function (type)
- {
- if (!type.any_cell_changed)
- return; // all instances must already be up-to-date
- var i, len, instances = type.instances;
- for (i = 0, len = instances.length; i < len; ++i)
- {
- instances[i].update_collision_cell();
- }
- var createRow = this.createRow;
- for (i = 0, len = createRow.length; i < len; ++i)
- {
- if (createRow[i].type === type)
- createRow[i].update_collision_cell();
- }
- type.any_cell_changed = false;
- };
- Runtime.prototype.getCollisionCandidates = function (layer, rtype, bbox, candidates)
- {
- var i, len, t;
- var is_parallaxed = (layer ? (layer.parallaxX !== 1 || layer.parallaxY !== 1) : false);
- if (rtype.is_family)
- {
- for (i = 0, len = rtype.members.length; i < len; ++i)
- {
- t = rtype.members[i];
- if (is_parallaxed || t.any_instance_parallaxed)
- {
- cr.appendArray(candidates, t.instances);
- }
- else
- {
- this.updateAllCells(t);
- t.collision_grid.queryRange(bbox, candidates);
- }
- }
- }
- else
- {
- if (is_parallaxed || rtype.any_instance_parallaxed)
- {
- cr.appendArray(candidates, rtype.instances);
- }
- else
- {
- this.updateAllCells(rtype);
- rtype.collision_grid.queryRange(bbox, candidates);
- }
- }
- };
- Runtime.prototype.getTypesCollisionCandidates = function (layer, types, bbox, candidates)
- {
- var i, len;
- for (i = 0, len = types.length; i < len; ++i)
- {
- this.getCollisionCandidates(layer, types[i], bbox, candidates);
- }
- };
- Runtime.prototype.getSolidCollisionCandidates = function (layer, bbox, candidates)
- {
- var solid = this.getSolidBehavior();
- if (!solid)
- return null;
- this.getTypesCollisionCandidates(layer, solid.my_types, bbox, candidates);
- };
- Runtime.prototype.getJumpthruCollisionCandidates = function (layer, bbox, candidates)
- {
- var jumpthru = this.getJumpthruBehavior();
- if (!jumpthru)
- return null;
- this.getTypesCollisionCandidates(layer, jumpthru.my_types, bbox, candidates);
- };
- Runtime.prototype.testAndSelectCanvasPointOverlap = function (type, ptx, pty, inverted)
- {
- var sol = type.getCurrentSol();
- var i, j, inst, len;
- var orblock = this.getCurrentEventStack().current_event.orblock;
- var lx, ly, arr;
- if (sol.select_all)
- {
- if (!inverted)
- {
- sol.select_all = false;
- cr.clearArray(sol.instances); // clear contents
- }
- for (i = 0, len = type.instances.length; i < len; i++)
- {
- inst = type.instances[i];
- inst.update_bbox();
- lx = inst.layer.canvasToLayer(ptx, pty, true);
- ly = inst.layer.canvasToLayer(ptx, pty, false);
- if (inst.contains_pt(lx, ly))
- {
- if (inverted)
- return false;
- else
- sol.instances.push(inst);
- }
- else if (orblock)
- sol.else_instances.push(inst);
- }
- }
- else
- {
- j = 0;
- arr = (orblock ? sol.else_instances : sol.instances);
- for (i = 0, len = arr.length; i < len; i++)
- {
- inst = arr[i];
- inst.update_bbox();
- lx = inst.layer.canvasToLayer(ptx, pty, true);
- ly = inst.layer.canvasToLayer(ptx, pty, false);
- if (inst.contains_pt(lx, ly))
- {
- if (inverted)
- return false;
- else if (orblock)
- sol.instances.push(inst);
- else
- {
- sol.instances[j] = sol.instances[i];
- j++;
- }
- }
- }
- if (!inverted)
- arr.length = j;
- }
- type.applySolToContainer();
- if (inverted)
- return true; // did not find anything overlapping
- else
- return sol.hasObjects();
- };
- Runtime.prototype.testOverlap = function (a, b)
- {
- if (!a || !b || a === b || !a.collisionsEnabled || !b.collisionsEnabled)
- return false;
- a.update_bbox();
- b.update_bbox();
- var layera = a.layer;
- var layerb = b.layer;
- var different_layers = (layera !== layerb && (layera.parallaxX !== layerb.parallaxX || layerb.parallaxY !== layerb.parallaxY || layera.scale !== layerb.scale || layera.angle !== layerb.angle || layera.zoomRate !== layerb.zoomRate));
- var i, len, i2, i21, x, y, haspolya, haspolyb, polya, polyb;
- if (!different_layers) // same layers: easy check
- {
- if (!a.bbox.intersects_rect(b.bbox))
- return false;
- if (!a.bquad.intersects_quad(b.bquad))
- return false;
- if (a.tilemap_exists && b.tilemap_exists)
- return false;
- if (a.tilemap_exists)
- return this.testTilemapOverlap(a, b);
- if (b.tilemap_exists)
- return this.testTilemapOverlap(b, a);
- haspolya = (a.collision_poly && !a.collision_poly.is_empty());
- haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
- if (!haspolya && !haspolyb)
- return true;
- if (haspolya)
- {
- a.collision_poly.cache_poly(a.width, a.height, a.angle);
- polya = a.collision_poly;
- }
- else
- {
- this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
- polya = this.temp_poly;
- }
- if (haspolyb)
- {
- b.collision_poly.cache_poly(b.width, b.height, b.angle);
- polyb = b.collision_poly;
- }
- else
- {
- this.temp_poly.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
- polyb = this.temp_poly;
- }
- return polya.intersects_poly(polyb, b.x - a.x, b.y - a.y);
- }
- else // different layers: need to do full translated check
- {
- haspolya = (a.collision_poly && !a.collision_poly.is_empty());
- haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
- if (haspolya)
- {
- a.collision_poly.cache_poly(a.width, a.height, a.angle);
- this.temp_poly.set_from_poly(a.collision_poly);
- }
- else
- {
- this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
- }
- polya = this.temp_poly;
- if (haspolyb)
- {
- b.collision_poly.cache_poly(b.width, b.height, b.angle);
- this.temp_poly2.set_from_poly(b.collision_poly);
- }
- else
- {
- this.temp_poly2.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
- }
- polyb = this.temp_poly2;
- for (i = 0, len = polya.pts_count; i < len; i++)
- {
- i2 = i * 2;
- i21 = i2 + 1;
- x = polya.pts_cache[i2];
- y = polya.pts_cache[i21];
- polya.pts_cache[i2] = layera.layerToCanvas(x + a.x, y + a.y, true);
- polya.pts_cache[i21] = layera.layerToCanvas(x + a.x, y + a.y, false);
- }
- polya.update_bbox();
- for (i = 0, len = polyb.pts_count; i < len; i++)
- {
- i2 = i * 2;
- i21 = i2 + 1;
- x = polyb.pts_cache[i2];
- y = polyb.pts_cache[i21];
- polyb.pts_cache[i2] = layerb.layerToCanvas(x + b.x, y + b.y, true);
- polyb.pts_cache[i21] = layerb.layerToCanvas(x + b.x, y + b.y, false);
- }
- polyb.update_bbox();
- return polya.intersects_poly(polyb, 0, 0);
- }
- };
- var tmpQuad = new cr.quad();
- var tmpRect = new cr.rect(0, 0, 0, 0);
- var collrect_candidates = [];
- Runtime.prototype.testTilemapOverlap = function (tm, a)
- {
- var i, len, c, rc;
- var bbox = a.bbox;
- var tmx = tm.x;
- var tmy = tm.y;
- tm.getCollisionRectCandidates(bbox, collrect_candidates);
- var collrects = collrect_candidates;
- var haspolya = (a.collision_poly && !a.collision_poly.is_empty());
- for (i = 0, len = collrects.length; i < len; ++i)
- {
- c = collrects[i];
- rc = c.rc;
- if (bbox.intersects_rect_off(rc, tmx, tmy))
- {
- tmpQuad.set_from_rect(rc);
- tmpQuad.offset(tmx, tmy);
- if (tmpQuad.intersects_quad(a.bquad))
- {
- if (haspolya)
- {
- a.collision_poly.cache_poly(a.width, a.height, a.angle);
- if (c.poly)
- {
- if (c.poly.intersects_poly(a.collision_poly, a.x - (tmx + rc.left), a.y - (tmy + rc.top)))
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- else
- {
- this.temp_poly.set_from_quad(tmpQuad, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
- if (this.temp_poly.intersects_poly(a.collision_poly, a.x, a.y))
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- }
- else
- {
- if (c.poly)
- {
- this.temp_poly.set_from_quad(a.bquad, 0, 0, a.width, a.height);
- if (c.poly.intersects_poly(this.temp_poly, -(tmx + rc.left), -(tmy + rc.top)))
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- else
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- }
- }
- }
- cr.clearArray(collrect_candidates);
- return false;
- };
- Runtime.prototype.testRectOverlap = function (r, b)
- {
- if (!b || !b.collisionsEnabled)
- return false;
- b.update_bbox();
- var layerb = b.layer;
- var haspolyb, polyb;
- if (!b.bbox.intersects_rect(r))
- return false;
- if (b.tilemap_exists)
- {
- b.getCollisionRectCandidates(r, collrect_candidates);
- var collrects = collrect_candidates;
- var i, len, c, tilerc;
- var tmx = b.x;
- var tmy = b.y;
- for (i = 0, len = collrects.length; i < len; ++i)
- {
- c = collrects[i];
- tilerc = c.rc;
- if (r.intersects_rect_off(tilerc, tmx, tmy))
- {
- if (c.poly)
- {
- this.temp_poly.set_from_rect(r, 0, 0);
- if (c.poly.intersects_poly(this.temp_poly, -(tmx + tilerc.left), -(tmy + tilerc.top)))
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- else
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- }
- cr.clearArray(collrect_candidates);
- return false;
- }
- else
- {
- tmpQuad.set_from_rect(r);
- if (!b.bquad.intersects_quad(tmpQuad))
- return false;
- haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
- if (!haspolyb)
- return true;
- b.collision_poly.cache_poly(b.width, b.height, b.angle);
- tmpQuad.offset(-r.left, -r.top);
- this.temp_poly.set_from_quad(tmpQuad, 0, 0, 1, 1);
- return b.collision_poly.intersects_poly(this.temp_poly, r.left - b.x, r.top - b.y);
- }
- };
- Runtime.prototype.testSegmentOverlap = function (x1, y1, x2, y2, b)
- {
- if (!b || !b.collisionsEnabled)
- return false;
- b.update_bbox();
- var layerb = b.layer;
- var haspolyb, polyb;
- tmpRect.set(cr.min(x1, x2), cr.min(y1, y2), cr.max(x1, x2), cr.max(y1, y2));
- if (!b.bbox.intersects_rect(tmpRect))
- return false;
- if (b.tilemap_exists)
- {
- b.getCollisionRectCandidates(tmpRect, collrect_candidates);
- var collrects = collrect_candidates;
- var i, len, c, tilerc;
- var tmx = b.x;
- var tmy = b.y;
- for (i = 0, len = collrects.length; i < len; ++i)
- {
- c = collrects[i];
- tilerc = c.rc;
- if (tmpRect.intersects_rect_off(tilerc, tmx, tmy))
- {
- tmpQuad.set_from_rect(tilerc);
- tmpQuad.offset(tmx, tmy);
- if (tmpQuad.intersects_segment(x1, y1, x2, y2))
- {
- if (c.poly)
- {
- if (c.poly.intersects_segment(tmx + tilerc.left, tmy + tilerc.top, x1, y1, x2, y2))
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- else
- {
- cr.clearArray(collrect_candidates);
- return true;
- }
- }
- }
- }
- cr.clearArray(collrect_candidates);
- return false;
- }
- else
- {
- if (!b.bquad.intersects_segment(x1, y1, x2, y2))
- return false;
- haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
- if (!haspolyb)
- return true;
- b.collision_poly.cache_poly(b.width, b.height, b.angle);
- return b.collision_poly.intersects_segment(b.x, b.y, x1, y1, x2, y2);
- }
- };
- Runtime.prototype.typeHasBehavior = function (t, b)
- {
- if (!b)
- return false;
- var i, len, j, lenj, f;
- for (i = 0, len = t.behaviors.length; i < len; i++)
- {
- if (t.behaviors[i].behavior instanceof b)
- return true;
- }
- if (!t.is_family)
- {
- for (i = 0, len = t.families.length; i < len; i++)
- {
- f = t.families[i];
- for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
- {
- if (f.behaviors[j].behavior instanceof b)
- return true;
- }
- }
- }
- return false;
- };
- Runtime.prototype.typeHasNoSaveBehavior = function (t)
- {
- return this.typeHasBehavior(t, cr.behaviors.NoSave);
- };
- Runtime.prototype.typeHasPersistBehavior = function (t)
- {
- return this.typeHasBehavior(t, cr.behaviors.Persist);
- };
- Runtime.prototype.getSolidBehavior = function ()
- {
- return this.solidBehavior;
- };
- Runtime.prototype.getJumpthruBehavior = function ()
- {
- return this.jumpthruBehavior;
- };
- var candidates = [];
- Runtime.prototype.testOverlapSolid = function (inst)
- {
- var i, len, s;
- inst.update_bbox();
- this.getSolidCollisionCandidates(inst.layer, inst.bbox, candidates);
- for (i = 0, len = candidates.length; i < len; ++i)
- {
- s = candidates[i];
- if (!s.extra["solidEnabled"])
- continue;
- if (this.testOverlap(inst, s))
- {
- cr.clearArray(candidates);
- return s;
- }
- }
- cr.clearArray(candidates);
- return null;
- };
- Runtime.prototype.testRectOverlapSolid = function (r)
- {
- var i, len, s;
- this.getSolidCollisionCandidates(null, r, candidates);
- for (i = 0, len = candidates.length; i < len; ++i)
- {
- s = candidates[i];
- if (!s.extra["solidEnabled"])
- continue;
- if (this.testRectOverlap(r, s))
- {
- cr.clearArray(candidates);
- return s;
- }
- }
- cr.clearArray(candidates);
- return null;
- };
- var jumpthru_array_ret = [];
- Runtime.prototype.testOverlapJumpThru = function (inst, all)
- {
- var ret = null;
- if (all)
- {
- ret = jumpthru_array_ret;
- cr.clearArray(ret);
- }
- inst.update_bbox();
- this.getJumpthruCollisionCandidates(inst.layer, inst.bbox, candidates);
- var i, len, j;
- for (i = 0, len = candidates.length; i < len; ++i)
- {
- j = candidates[i];
- if (!j.extra["jumpthruEnabled"])
- continue;
- if (this.testOverlap(inst, j))
- {
- if (all)
- ret.push(j);
- else
- {
- cr.clearArray(candidates);
- return j;
- }
- }
- }
- cr.clearArray(candidates);
- return ret;
- };
- Runtime.prototype.pushOutSolid = function (inst, xdir, ydir, dist, include_jumpthrus, specific_jumpthru)
- {
- var push_dist = dist || 50;
- var oldx = inst.x
- var oldy = inst.y;
- var i;
- var last_overlapped = null, secondlast_overlapped = null;
- for (i = 0; i < push_dist; i++)
- {
- inst.x = (oldx + (xdir * i));
- inst.y = (oldy + (ydir * i));
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, last_overlapped))
- {
- last_overlapped = this.testOverlapSolid(inst);
- if (last_overlapped)
- secondlast_overlapped = last_overlapped;
- if (!last_overlapped)
- {
- if (include_jumpthrus)
- {
- if (specific_jumpthru)
- last_overlapped = (this.testOverlap(inst, specific_jumpthru) ? specific_jumpthru : null);
- else
- last_overlapped = this.testOverlapJumpThru(inst);
- if (last_overlapped)
- secondlast_overlapped = last_overlapped;
- }
- if (!last_overlapped)
- {
- if (secondlast_overlapped)
- this.pushInFractional(inst, xdir, ydir, secondlast_overlapped, 16);
- return true;
- }
- }
- }
- }
- inst.x = oldx;
- inst.y = oldy;
- inst.set_bbox_changed();
- return false;
- };
- Runtime.prototype.pushOutSolidAxis = function(inst, xdir, ydir, dist)
- {
- dist = dist || 50;
- var oldX = inst.x;
- var oldY = inst.y;
- var lastOverlapped = null;
- var secondLastOverlapped = null;
- var i, which, sign;
- for (i = 0; i < dist; ++i)
- {
- for (which = 0; which < 2; ++which)
- {
- sign = which * 2 - 1; // -1 or 1
- inst.x = oldX + (xdir * i * sign);
- inst.y = oldY + (ydir * i * sign);
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, lastOverlapped))
- {
- lastOverlapped = this.testOverlapSolid(inst);
- if (lastOverlapped)
- {
- secondLastOverlapped = lastOverlapped;
- }
- else
- {
- if (secondLastOverlapped)
- this.pushInFractional(inst, xdir * sign, ydir * sign, secondLastOverlapped, 16);
- return true;
- }
- }
- }
- }
- inst.x = oldX;
- inst.y = oldY;
- inst.set_bbox_changed();
- return false;
- };
- Runtime.prototype.pushOut = function (inst, xdir, ydir, dist, otherinst)
- {
- var push_dist = dist || 50;
- var oldx = inst.x
- var oldy = inst.y;
- var i;
- for (i = 0; i < push_dist; i++)
- {
- inst.x = (oldx + (xdir * i));
- inst.y = (oldy + (ydir * i));
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, otherinst))
- return true;
- }
- inst.x = oldx;
- inst.y = oldy;
- inst.set_bbox_changed();
- return false;
- };
- Runtime.prototype.pushInFractional = function (inst, xdir, ydir, obj, limit)
- {
- var divisor = 2;
- var frac;
- var forward = false;
- var overlapping = false;
- var bestx = inst.x;
- var besty = inst.y;
- while (divisor <= limit)
- {
- frac = 1 / divisor;
- divisor *= 2;
- inst.x += xdir * frac * (forward ? 1 : -1);
- inst.y += ydir * frac * (forward ? 1 : -1);
- inst.set_bbox_changed();
- if (this.testOverlap(inst, obj))
- {
- forward = true;
- overlapping = true;
- }
- else
- {
- forward = false;
- overlapping = false;
- bestx = inst.x;
- besty = inst.y;
- }
- }
- if (overlapping)
- {
- inst.x = bestx;
- inst.y = besty;
- inst.set_bbox_changed();
- }
- };
- Runtime.prototype.pushOutSolidNearest = function (inst, max_dist_)
- {
- var max_dist = (cr.is_undefined(max_dist_) ? 100 : max_dist_);
- var dist = 0;
- var oldx = inst.x
- var oldy = inst.y;
- var dir = 0;
- var dx = 0, dy = 0;
- var last_overlapped = this.testOverlapSolid(inst);
- if (!last_overlapped)
- return true; // already clear of solids
- while (dist <= max_dist)
- {
- switch (dir) {
- case 0: dx = 0; dy = -1; dist++; break;
- case 1: dx = 1; dy = -1; break;
- case 2: dx = 1; dy = 0; break;
- case 3: dx = 1; dy = 1; break;
- case 4: dx = 0; dy = 1; break;
- case 5: dx = -1; dy = 1; break;
- case 6: dx = -1; dy = 0; break;
- case 7: dx = -1; dy = -1; break;
- }
- dir = (dir + 1) % 8;
- inst.x = cr.floor(oldx + (dx * dist));
- inst.y = cr.floor(oldy + (dy * dist));
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, last_overlapped))
- {
- last_overlapped = this.testOverlapSolid(inst);
- if (!last_overlapped)
- return true;
- }
- }
- inst.x = oldx;
- inst.y = oldy;
- inst.set_bbox_changed();
- return false;
- };
- Runtime.prototype.registerCollision = function (a, b)
- {
- if (!a.collisionsEnabled || !b.collisionsEnabled)
- return;
- this.registered_collisions.push([a, b]);
- };
- Runtime.prototype.addRegisteredCollisionCandidates = function (inst, otherType, arr)
- {
- var i, len, r, otherInst;
- for (i = 0, len = this.registered_collisions.length; i < len; ++i)
- {
- r = this.registered_collisions[i];
- if (r[0] === inst)
- otherInst = r[1];
- else if (r[1] === inst)
- otherInst = r[0];
- else
- continue;
- if (otherType.is_family)
- {
- if (otherType.members.indexOf(otherType) === -1)
- continue;
- }
- else
- {
- if (otherInst.type !== otherType)
- continue;
- }
- if (arr.indexOf(otherInst) === -1)
- arr.push(otherInst);
- }
- };
- Runtime.prototype.checkRegisteredCollision = function (a, b)
- {
- var i, len, x;
- for (i = 0, len = this.registered_collisions.length; i < len; i++)
- {
- x = this.registered_collisions[i];
- if ((x[0] === a && x[1] === b) || (x[0] === b && x[1] === a))
- return true;
- }
- return false;
- };
- Runtime.prototype.calculateSolidBounceAngle = function(inst, startx, starty, obj)
- {
- var objx = inst.x;
- var objy = inst.y;
- var radius = cr.max(10, cr.distanceTo(startx, starty, objx, objy));
- var startangle = cr.angleTo(startx, starty, objx, objy);
- var firstsolid = obj || this.testOverlapSolid(inst);
- if (!firstsolid)
- return cr.clamp_angle(startangle + cr.PI);
- var cursolid = firstsolid;
- var i, curangle, anticlockwise_free_angle, clockwise_free_angle;
- var increment = cr.to_radians(5); // 5 degree increments
- for (i = 1; i < 36; i++)
- {
- curangle = startangle - i * increment;
- inst.x = startx + Math.cos(curangle) * radius;
- inst.y = starty + Math.sin(curangle) * radius;
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, cursolid))
- {
- cursolid = obj ? null : this.testOverlapSolid(inst);
- if (!cursolid)
- {
- anticlockwise_free_angle = curangle;
- break;
- }
- }
- }
- if (i === 36)
- anticlockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
- var cursolid = firstsolid;
- for (i = 1; i < 36; i++)
- {
- curangle = startangle + i * increment;
- inst.x = startx + Math.cos(curangle) * radius;
- inst.y = starty + Math.sin(curangle) * radius;
- inst.set_bbox_changed();
- if (!this.testOverlap(inst, cursolid))
- {
- cursolid = obj ? null : this.testOverlapSolid(inst);
- if (!cursolid)
- {
- clockwise_free_angle = curangle;
- break;
- }
- }
- }
- if (i === 36)
- clockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
- inst.x = objx;
- inst.y = objy;
- inst.set_bbox_changed();
- if (clockwise_free_angle === anticlockwise_free_angle)
- return clockwise_free_angle;
- var half_diff = cr.angleDiff(clockwise_free_angle, anticlockwise_free_angle) / 2;
- var normal;
- if (cr.angleClockwise(clockwise_free_angle, anticlockwise_free_angle))
- {
- normal = cr.clamp_angle(anticlockwise_free_angle + half_diff + cr.PI);
- }
- else
- {
- normal = cr.clamp_angle(clockwise_free_angle + half_diff);
- }
-;
- var vx = Math.cos(startangle);
- var vy = Math.sin(startangle);
- var nx = Math.cos(normal);
- var ny = Math.sin(normal);
- var v_dot_n = vx * nx + vy * ny;
- var rx = vx - 2 * v_dot_n * nx;
- var ry = vy - 2 * v_dot_n * ny;
- return cr.angleTo(0, 0, rx, ry);
- };
- var triggerSheetIndex = -1;
- Runtime.prototype.trigger = function (method, inst, value /* for fast triggers */)
- {
-;
- if (!this.running_layout)
- return false;
- var sheet = this.running_layout.event_sheet;
- if (!sheet)
- return false; // no event sheet active; nothing to trigger
- var ret = false;
- var r, i, len;
- triggerSheetIndex++;
- var deep_includes = sheet.deep_includes;
- for (i = 0, len = deep_includes.length; i < len; ++i)
- {
- r = this.triggerOnSheet(method, inst, deep_includes[i], value);
- ret = ret || r;
- }
- r = this.triggerOnSheet(method, inst, sheet, value);
- ret = ret || r;
- triggerSheetIndex--;
- return ret;
- };
- Runtime.prototype.triggerOnSheet = function (method, inst, sheet, value)
- {
- var ret = false;
- var i, leni, r, families;
- if (!inst)
- {
- r = this.triggerOnSheetForTypeName(method, inst, "system", sheet, value);
- ret = ret || r;
- }
- else
- {
- r = this.triggerOnSheetForTypeName(method, inst, inst.type.name, sheet, value);
- ret = ret || r;
- families = inst.type.families;
- for (i = 0, leni = families.length; i < leni; ++i)
- {
- r = this.triggerOnSheetForTypeName(method, inst, families[i].name, sheet, value);
- ret = ret || r;
- }
- }
- return ret; // true if anything got triggered
- };
- Runtime.prototype.triggerOnSheetForTypeName = function (method, inst, type_name, sheet, value)
- {
- var i, leni;
- var ret = false, ret2 = false;
- var trig, index;
- var fasttrigger = (typeof value !== "undefined");
- var triggers = (fasttrigger ? sheet.fasttriggers : sheet.triggers);
- var obj_entry = triggers[type_name];
- if (!obj_entry)
- return ret;
- var triggers_list = null;
- for (i = 0, leni = obj_entry.length; i < leni; ++i)
- {
- if (obj_entry[i].method == method)
- {
- triggers_list = obj_entry[i].evs;
- break;
- }
- }
- if (!triggers_list)
- return ret;
- var triggers_to_fire;
- if (fasttrigger)
- {
- triggers_to_fire = triggers_list[value];
- }
- else
- {
- triggers_to_fire = triggers_list;
- }
- if (!triggers_to_fire)
- return null;
- for (i = 0, leni = triggers_to_fire.length; i < leni; i++)
- {
- trig = triggers_to_fire[i][0];
- index = triggers_to_fire[i][1];
- ret2 = this.executeSingleTrigger(inst, type_name, trig, index);
- ret = ret || ret2;
- }
- return ret;
- };
- Runtime.prototype.executeSingleTrigger = function (inst, type_name, trig, index)
- {
- var i, leni;
- var ret = false;
- this.trigger_depth++;
- var current_event = this.getCurrentEventStack().current_event;
- if (current_event)
- this.pushCleanSol(current_event.solModifiersIncludingParents);
- var isrecursive = (this.trigger_depth > 1); // calling trigger from inside another trigger
- this.pushCleanSol(trig.solModifiersIncludingParents);
- if (isrecursive)
- this.pushLocalVarStack();
- var event_stack = this.pushEventStack(trig);
- event_stack.current_event = trig;
- if (inst)
- {
- var sol = this.types[type_name].getCurrentSol();
- sol.select_all = false;
- cr.clearArray(sol.instances);
- sol.instances[0] = inst;
- this.types[type_name].applySolToContainer();
- }
- var ok_to_run = true;
- if (trig.parent)
- {
- var temp_parents_arr = event_stack.temp_parents_arr;
- var cur_parent = trig.parent;
- while (cur_parent)
- {
- temp_parents_arr.push(cur_parent);
- cur_parent = cur_parent.parent;
- }
- temp_parents_arr.reverse();
- for (i = 0, leni = temp_parents_arr.length; i < leni; i++)
- {
- if (!temp_parents_arr[i].run_pretrigger()) // parent event failed
- {
- ok_to_run = false;
- break;
- }
- }
- }
- if (ok_to_run)
- {
- this.execcount++;
- if (trig.orblock)
- trig.run_orblocktrigger(index);
- else
- trig.run();
- ret = ret || event_stack.last_event_true;
- }
- this.popEventStack();
- if (isrecursive)
- this.popLocalVarStack();
- this.popSol(trig.solModifiersIncludingParents);
- if (current_event)
- this.popSol(current_event.solModifiersIncludingParents);
- if (this.hasPendingInstances && this.isInOnDestroy === 0 && triggerSheetIndex === 0 && !this.isRunningEvents)
- {
- this.ClearDeathRow();
- }
- this.trigger_depth--;
- return ret;
- };
- Runtime.prototype.getCurrentCondition = function ()
- {
- var evinfo = this.getCurrentEventStack();
- return evinfo.current_event.conditions[evinfo.cndindex];
- };
- Runtime.prototype.getCurrentConditionObjectType = function ()
- {
- var cnd = this.getCurrentCondition();
- return cnd.type;
- };
- Runtime.prototype.isCurrentConditionFirst = function ()
- {
- var evinfo = this.getCurrentEventStack();
- return evinfo.cndindex === 0;
- };
- Runtime.prototype.getCurrentAction = function ()
- {
- var evinfo = this.getCurrentEventStack();
- return evinfo.current_event.actions[evinfo.actindex];
- };
- Runtime.prototype.pushLocalVarStack = function ()
- {
- this.localvar_stack_index++;
- if (this.localvar_stack_index >= this.localvar_stack.length)
- this.localvar_stack.push([]);
- };
- Runtime.prototype.popLocalVarStack = function ()
- {
-;
- this.localvar_stack_index--;
- };
- Runtime.prototype.getCurrentLocalVarStack = function ()
- {
- return this.localvar_stack[this.localvar_stack_index];
- };
- Runtime.prototype.pushEventStack = function (cur_event)
- {
- this.event_stack_index++;
- if (this.event_stack_index >= this.event_stack.length)
- this.event_stack.push(new cr.eventStackFrame());
- var ret = this.getCurrentEventStack();
- ret.reset(cur_event);
- return ret;
- };
- Runtime.prototype.popEventStack = function ()
- {
-;
- this.event_stack_index--;
- };
- Runtime.prototype.getCurrentEventStack = function ()
- {
- return this.event_stack[this.event_stack_index];
- };
- Runtime.prototype.pushLoopStack = function (name_)
- {
- this.loop_stack_index++;
- if (this.loop_stack_index >= this.loop_stack.length)
- {
- this.loop_stack.push(cr.seal({ name: name_, index: 0, stopped: false }));
- }
- var ret = this.getCurrentLoop();
- ret.name = name_;
- ret.index = 0;
- ret.stopped = false;
- return ret;
- };
- Runtime.prototype.popLoopStack = function ()
- {
-;
- this.loop_stack_index--;
- };
- Runtime.prototype.getCurrentLoop = function ()
- {
- return this.loop_stack[this.loop_stack_index];
- };
- Runtime.prototype.getEventVariableByName = function (name, scope)
- {
- var i, leni, j, lenj, sheet, e;
- while (scope)
- {
- for (i = 0, leni = scope.subevents.length; i < leni; i++)
- {
- e = scope.subevents[i];
- if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
- return e;
- }
- scope = scope.parent;
- }
- for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
- {
- sheet = this.eventsheets_by_index[i];
- for (j = 0, lenj = sheet.events.length; j < lenj; j++)
- {
- e = sheet.events[j];
- if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
- return e;
- }
- }
- return null;
- };
- Runtime.prototype.getLayoutBySid = function (sid_)
- {
- var i, len;
- for (i = 0, len = this.layouts_by_index.length; i < len; i++)
- {
- if (this.layouts_by_index[i].sid === sid_)
- return this.layouts_by_index[i];
- }
- return null;
- };
- Runtime.prototype.getObjectTypeBySid = function (sid_)
- {
- var i, len;
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- if (this.types_by_index[i].sid === sid_)
- return this.types_by_index[i];
- }
- return null;
- };
- Runtime.prototype.getGroupBySid = function (sid_)
- {
- var i, len;
- for (i = 0, len = this.allGroups.length; i < len; i++)
- {
- if (this.allGroups[i].sid === sid_)
- return this.allGroups[i];
- }
- return null;
- };
- Runtime.prototype.doCanvasSnapshot = function (format_, quality_)
- {
- this.snapshotCanvas = [format_, quality_];
- this.redraw = true; // force redraw so snapshot is always taken
- };
- function IsIndexedDBAvailable()
- {
- try {
- return !!window.indexedDB;
- }
- catch (e)
- {
- return false;
- }
- };
- function makeSaveDb(e)
- {
- var db = e.target.result;
- db.createObjectStore("saves", { keyPath: "slot" });
- };
- function IndexedDB_WriteSlot(slot_, data_, oncomplete_, onerror_)
- {
- try {
- var request = indexedDB.open("_C2SaveStates");
- request.onupgradeneeded = makeSaveDb;
- request.onerror = onerror_;
- request.onsuccess = function (e)
- {
- var db = e.target.result;
- db.onerror = onerror_;
- var transaction = db.transaction(["saves"], "readwrite");
- var objectStore = transaction.objectStore("saves");
- var putReq = objectStore.put({"slot": slot_, "data": data_ });
- putReq.onsuccess = oncomplete_;
- };
- }
- catch (err)
- {
- onerror_(err);
- }
- };
- function IndexedDB_ReadSlot(slot_, oncomplete_, onerror_)
- {
- try {
- var request = indexedDB.open("_C2SaveStates");
- request.onupgradeneeded = makeSaveDb;
- request.onerror = onerror_;
- request.onsuccess = function (e)
- {
- var db = e.target.result;
- db.onerror = onerror_;
- var transaction = db.transaction(["saves"]);
- var objectStore = transaction.objectStore("saves");
- var readReq = objectStore.get(slot_);
- readReq.onsuccess = function (e)
- {
- if (readReq.result)
- oncomplete_(readReq.result["data"]);
- else
- oncomplete_(null);
- };
- };
- }
- catch (err)
- {
- onerror_(err);
- }
- };
- Runtime.prototype.signalContinuousPreview = function ()
- {
- this.signalledContinuousPreview = true;
- };
- function doContinuousPreviewReload()
- {
- cr.logexport("Reloading for continuous preview");
- if (!!window["c2cocoonjs"])
- {
- CocoonJS["App"]["reload"]();
- }
- else
- {
- if (window.location.search.indexOf("continuous") > -1)
- window.location.reload(true);
- else
- window.location = window.location + "?continuous";
- }
- };
- Runtime.prototype.handleSaveLoad = function ()
- {
- var self = this;
- var savingToSlot = this.saveToSlot;
- var savingJson = this.lastSaveJson;
- var loadingFromSlot = this.loadFromSlot;
- var continuous = false;
- if (this.signalledContinuousPreview)
- {
- continuous = true;
- savingToSlot = "__c2_continuouspreview";
- this.signalledContinuousPreview = false;
- }
- if (savingToSlot.length)
- {
- this.ClearDeathRow();
- savingJson = this.saveToJSONString();
- if (IsIndexedDBAvailable() && !this.isCocoonJs)
- {
- IndexedDB_WriteSlot(savingToSlot, savingJson, function ()
- {
- cr.logexport("Saved state to IndexedDB storage (" + savingJson.length + " bytes)");
- self.lastSaveJson = savingJson;
- self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
- self.lastSaveJson = "";
- savingJson = "";
- if (continuous)
- doContinuousPreviewReload();
- }, function (e)
- {
- try {
- localStorage.setItem("__c2save_" + savingToSlot, savingJson);
- cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
- self.lastSaveJson = savingJson;
- self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
- self.lastSaveJson = "";
- savingJson = "";
- if (continuous)
- doContinuousPreviewReload();
- }
- catch (f)
- {
- cr.logexport("Failed to save game state: " + e + "; " + f);
- self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
- }
- });
- }
- else
- {
- try {
- localStorage.setItem("__c2save_" + savingToSlot, savingJson);
- cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
- self.lastSaveJson = savingJson;
- this.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
- self.lastSaveJson = "";
- savingJson = "";
- if (continuous)
- doContinuousPreviewReload();
- }
- catch (e)
- {
- cr.logexport("Error saving to WebStorage: " + e);
- self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
- }
- }
- this.saveToSlot = "";
- this.loadFromSlot = "";
- this.loadFromJson = null;
- }
- if (loadingFromSlot.length)
- {
- if (IsIndexedDBAvailable() && !this.isCocoonJs)
- {
- IndexedDB_ReadSlot(loadingFromSlot, function (result_)
- {
- if (result_)
- {
- self.loadFromJson = result_;
- cr.logexport("Loaded state from IndexedDB storage (" + self.loadFromJson.length + " bytes)");
- }
- else
- {
- self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
- cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
- }
- self.suspendDrawing = false;
- if (!self.loadFromJson)
- {
- self.loadFromJson = null;
- self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
- }
- }, function (e)
- {
- self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
- cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
- self.suspendDrawing = false;
- if (!self.loadFromJson)
- {
- self.loadFromJson = null;
- self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
- }
- });
- }
- else
- {
- try {
- this.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
- cr.logexport("Loaded state from WebStorage (" + this.loadFromJson.length + " bytes)");
- }
- catch (e)
- {
- this.loadFromJson = null;
- }
- this.suspendDrawing = false;
- if (!self.loadFromJson)
- {
- self.loadFromJson = null;
- self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
- }
- }
- this.loadFromSlot = "";
- this.saveToSlot = "";
- }
- if (this.loadFromJson !== null)
- {
- this.ClearDeathRow();
- var ok = this.loadFromJSONString(this.loadFromJson);
- if (ok)
- {
- this.lastSaveJson = this.loadFromJson;
- this.trigger(cr.system_object.prototype.cnds.OnLoadComplete, null);
- this.lastSaveJson = "";
- }
- else
- {
- self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
- }
- this.loadFromJson = null;
- }
- };
- function CopyExtraObject(extra)
- {
- var p, ret = {};
- for (p in extra)
- {
- if (extra.hasOwnProperty(p))
- {
- if (extra[p] instanceof cr.ObjectSet)
- continue;
- if (extra[p] && typeof extra[p].c2userdata !== "undefined")
- continue;
- if (p === "spriteCreatedDestroyCallback")
- continue;
- ret[p] = extra[p];
- }
- }
- return ret;
- };
- Runtime.prototype.saveToJSONString = function()
- {
- var i, len, j, lenj, type, layout, typeobj, g, c, a, v, p;
- var o = {
- "c2save": true,
- "version": 1,
- "rt": {
- "time": this.kahanTime.sum,
- "walltime": this.wallTime.sum,
- "timescale": this.timescale,
- "tickcount": this.tickcount,
- "execcount": this.execcount,
- "next_uid": this.next_uid,
- "running_layout": this.running_layout.sid,
- "start_time_offset": (Date.now() - this.start_time)
- },
- "types": {},
- "layouts": {},
- "events": {
- "groups": {},
- "cnds": {},
- "acts": {},
- "vars": {}
- }
- };
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family || this.typeHasNoSaveBehavior(type))
- continue;
- typeobj = {
- "instances": []
- };
- if (cr.hasAnyOwnProperty(type.extra))
- typeobj["ex"] = CopyExtraObject(type.extra);
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- typeobj["instances"].push(this.saveInstanceToJSON(type.instances[j]));
- }
- o["types"][type.sid.toString()] = typeobj;
- }
- for (i = 0, len = this.layouts_by_index.length; i < len; i++)
- {
- layout = this.layouts_by_index[i];
- o["layouts"][layout.sid.toString()] = layout.saveToJSON();
- }
- var ogroups = o["events"]["groups"];
- for (i = 0, len = this.allGroups.length; i < len; i++)
- {
- g = this.allGroups[i];
- ogroups[g.sid.toString()] = this.groups_by_name[g.group_name].group_active;
- }
- var ocnds = o["events"]["cnds"];
- for (p in this.cndsBySid)
- {
- if (this.cndsBySid.hasOwnProperty(p))
- {
- c = this.cndsBySid[p];
- if (cr.hasAnyOwnProperty(c.extra))
- ocnds[p] = { "ex": CopyExtraObject(c.extra) };
- }
- }
- var oacts = o["events"]["acts"];
- for (p in this.actsBySid)
- {
- if (this.actsBySid.hasOwnProperty(p))
- {
- a = this.actsBySid[p];
- if (cr.hasAnyOwnProperty(a.extra))
- oacts[p] = { "ex": CopyExtraObject(a.extra) };
- }
- }
- var ovars = o["events"]["vars"];
- for (p in this.varsBySid)
- {
- if (this.varsBySid.hasOwnProperty(p))
- {
- v = this.varsBySid[p];
- if (!v.is_constant && (!v.parent || v.is_static))
- ovars[p] = v.data;
- }
- }
- o["system"] = this.system.saveToJSON();
- return JSON.stringify(o);
- };
- Runtime.prototype.refreshUidMap = function ()
- {
- var i, len, type, j, lenj, inst;
- this.objectsByUid = {};
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family)
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- this.objectsByUid[inst.uid.toString()] = inst;
- }
- }
- };
- Runtime.prototype.loadFromJSONString = function (str)
- {
- var o;
- try {
- o = JSON.parse(str);
- }
- catch (e) {
- return false;
- }
- if (!o["c2save"])
- return false; // probably not a c2 save state
- if (o["version"] > 1)
- return false; // from future version of c2; assume not compatible
- this.isLoadingState = true;
- var rt = o["rt"];
- this.kahanTime.reset();
- this.kahanTime.sum = rt["time"];
- this.wallTime.reset();
- this.wallTime.sum = rt["walltime"] || 0;
- this.timescale = rt["timescale"];
- this.tickcount = rt["tickcount"];
- this.execcount = rt["execcount"];
- this.start_time = Date.now() - rt["start_time_offset"];
- var layout_sid = rt["running_layout"];
- if (layout_sid !== this.running_layout.sid)
- {
- var changeToLayout = this.getLayoutBySid(layout_sid);
- if (changeToLayout)
- this.doChangeLayout(changeToLayout);
- else
- return; // layout that was saved on has gone missing (deleted?)
- }
- var i, len, j, lenj, k, lenk, p, type, existing_insts, load_insts, inst, binst, layout, layer, g, iid, t;
- var otypes = o["types"];
- for (p in otypes)
- {
- if (otypes.hasOwnProperty(p))
- {
- type = this.getObjectTypeBySid(parseInt(p, 10));
- if (!type || type.is_family || this.typeHasNoSaveBehavior(type))
- continue;
- if (otypes[p]["ex"])
- type.extra = otypes[p]["ex"];
- else
- cr.wipe(type.extra);
- existing_insts = type.instances;
- load_insts = otypes[p]["instances"];
- for (i = 0, len = cr.min(existing_insts.length, load_insts.length); i < len; i++)
- {
- this.loadInstanceFromJSON(existing_insts[i], load_insts[i]);
- }
- for (i = load_insts.length, len = existing_insts.length; i < len; i++)
- this.DestroyInstance(existing_insts[i]);
- for (i = existing_insts.length, len = load_insts.length; i < len; i++)
- {
- layer = null;
- if (type.plugin.is_world)
- {
- layer = this.running_layout.getLayerBySid(load_insts[i]["w"]["l"]);
- if (!layer)
- continue;
- }
- inst = this.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
- this.loadInstanceFromJSON(inst, load_insts[i]);
- }
- type.stale_iids = true;
- }
- }
- this.ClearDeathRow();
- this.refreshUidMap();
- var olayouts = o["layouts"];
- for (p in olayouts)
- {
- if (olayouts.hasOwnProperty(p))
- {
- layout = this.getLayoutBySid(parseInt(p, 10));
- if (!layout)
- continue; // must've gone missing
- layout.loadFromJSON(olayouts[p]);
- }
- }
- var ogroups = o["events"]["groups"];
- for (p in ogroups)
- {
- if (ogroups.hasOwnProperty(p))
- {
- g = this.getGroupBySid(parseInt(p, 10));
- if (g && this.groups_by_name[g.group_name])
- this.groups_by_name[g.group_name].setGroupActive(ogroups[p]);
- }
- }
- var ocnds = o["events"]["cnds"];
- for (p in this.cndsBySid)
- {
- if (this.cndsBySid.hasOwnProperty(p))
- {
- if (ocnds.hasOwnProperty(p))
- {
- this.cndsBySid[p].extra = ocnds[p]["ex"];
- }
- else
- {
- this.cndsBySid[p].extra = {};
- }
- }
- }
- var oacts = o["events"]["acts"];
- for (p in this.actsBySid)
- {
- if (this.actsBySid.hasOwnProperty(p))
- {
- if (oacts.hasOwnProperty(p))
- {
- this.actsBySid[p].extra = oacts[p]["ex"];
- }
- else
- {
- this.actsBySid[p].extra = {};
- }
- }
- }
- var ovars = o["events"]["vars"];
- for (p in ovars)
- {
- if (ovars.hasOwnProperty(p) && this.varsBySid.hasOwnProperty(p))
- {
- this.varsBySid[p].data = ovars[p];
- }
- }
- this.next_uid = rt["next_uid"];
- this.isLoadingState = false;
- for (i = 0, len = this.fireOnCreateAfterLoad.length; i < len; ++i)
- {
- inst = this.fireOnCreateAfterLoad[i];
- this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
- }
- cr.clearArray(this.fireOnCreateAfterLoad);
- this.system.loadFromJSON(o["system"]);
- for (i = 0, len = this.types_by_index.length; i < len; i++)
- {
- type = this.types_by_index[i];
- if (type.is_family || this.typeHasNoSaveBehavior(type))
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- {
- inst = type.instances[j];
- if (type.is_contained)
- {
- iid = inst.get_iid();
- cr.clearArray(inst.siblings);
- for (k = 0, lenk = type.container.length; k < lenk; k++)
- {
- t = type.container[k];
- if (type === t)
- continue;
-;
- inst.siblings.push(t.instances[iid]);
- }
- }
- if (inst.afterLoad)
- inst.afterLoad();
- if (inst.behavior_insts)
- {
- for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
- {
- binst = inst.behavior_insts[k];
- if (binst.afterLoad)
- binst.afterLoad();
- }
- }
- }
- }
- this.redraw = true;
- return true;
- };
- Runtime.prototype.saveInstanceToJSON = function(inst, state_only)
- {
- var i, len, world, behinst, et;
- var type = inst.type;
- var plugin = type.plugin;
- var o = {};
- if (state_only)
- o["c2"] = true; // mark as known json data from Construct 2
- else
- o["uid"] = inst.uid;
- if (cr.hasAnyOwnProperty(inst.extra))
- o["ex"] = CopyExtraObject(inst.extra);
- if (inst.instance_vars && inst.instance_vars.length)
- {
- o["ivs"] = {};
- for (i = 0, len = inst.instance_vars.length; i < len; i++)
- {
- o["ivs"][inst.type.instvar_sids[i].toString()] = inst.instance_vars[i];
- }
- }
- if (plugin.is_world)
- {
- world = {
- "x": inst.x,
- "y": inst.y,
- "w": inst.width,
- "h": inst.height,
- "l": inst.layer.sid,
- "zi": inst.get_zindex()
- };
- if (inst.angle !== 0)
- world["a"] = inst.angle;
- if (inst.opacity !== 1)
- world["o"] = inst.opacity;
- if (inst.hotspotX !== 0.5)
- world["hX"] = inst.hotspotX;
- if (inst.hotspotY !== 0.5)
- world["hY"] = inst.hotspotY;
- if (inst.blend_mode !== 0)
- world["bm"] = inst.blend_mode;
- if (!inst.visible)
- world["v"] = inst.visible;
- if (!inst.collisionsEnabled)
- world["ce"] = inst.collisionsEnabled;
- if (inst.my_timescale !== -1)
- world["mts"] = inst.my_timescale;
- if (type.effect_types.length)
- {
- world["fx"] = [];
- for (i = 0, len = type.effect_types.length; i < len; i++)
- {
- et = type.effect_types[i];
- world["fx"].push({"name": et.name,
- "active": inst.active_effect_flags[et.index],
- "params": inst.effect_params[et.index] });
- }
- }
- o["w"] = world;
- }
- if (inst.behavior_insts && inst.behavior_insts.length)
- {
- o["behs"] = {};
- for (i = 0, len = inst.behavior_insts.length; i < len; i++)
- {
- behinst = inst.behavior_insts[i];
- if (behinst.saveToJSON)
- o["behs"][behinst.type.sid.toString()] = behinst.saveToJSON();
- }
- }
- if (inst.saveToJSON)
- o["data"] = inst.saveToJSON();
- return o;
- };
- Runtime.prototype.getInstanceVarIndexBySid = function (type, sid_)
- {
- var i, len;
- for (i = 0, len = type.instvar_sids.length; i < len; i++)
- {
- if (type.instvar_sids[i] === sid_)
- return i;
- }
- return -1;
- };
- Runtime.prototype.getBehaviorIndexBySid = function (inst, sid_)
- {
- var i, len;
- for (i = 0, len = inst.behavior_insts.length; i < len; i++)
- {
- if (inst.behavior_insts[i].type.sid === sid_)
- return i;
- }
- return -1;
- };
- Runtime.prototype.loadInstanceFromJSON = function(inst, o, state_only)
- {
- var p, i, len, iv, oivs, world, fxindex, obehs, behindex, value;
- var oldlayer;
- var type = inst.type;
- var plugin = type.plugin;
- if (state_only)
- {
- if (!o["c2"])
- return;
- }
- else
- inst.uid = o["uid"];
- if (o["ex"])
- inst.extra = o["ex"];
- else
- cr.wipe(inst.extra);
- oivs = o["ivs"];
- if (oivs)
- {
- for (p in oivs)
- {
- if (oivs.hasOwnProperty(p))
- {
- iv = this.getInstanceVarIndexBySid(type, parseInt(p, 10));
- if (iv < 0 || iv >= inst.instance_vars.length)
- continue; // must've gone missing
- value = oivs[p];
- if (value === null)
- value = NaN;
- inst.instance_vars[iv] = value;
- }
- }
- }
- if (plugin.is_world)
- {
- world = o["w"];
- if (inst.layer.sid !== world["l"])
- {
- oldlayer = inst.layer;
- inst.layer = this.running_layout.getLayerBySid(world["l"]);
- if (inst.layer)
- {
- oldlayer.removeFromInstanceList(inst, true);
- inst.layer.appendToInstanceList(inst, true);
- inst.set_bbox_changed();
- inst.layer.setZIndicesStaleFrom(0);
- }
- else
- {
- inst.layer = oldlayer;
- if (!state_only)
- this.DestroyInstance(inst);
- }
- }
- inst.x = world["x"];
- inst.y = world["y"];
- inst.width = world["w"];
- inst.height = world["h"];
- inst.zindex = world["zi"];
- inst.angle = world.hasOwnProperty("a") ? world["a"] : 0;
- inst.opacity = world.hasOwnProperty("o") ? world["o"] : 1;
- inst.hotspotX = world.hasOwnProperty("hX") ? world["hX"] : 0.5;
- inst.hotspotY = world.hasOwnProperty("hY") ? world["hY"] : 0.5;
- inst.visible = world.hasOwnProperty("v") ? world["v"] : true;
- inst.collisionsEnabled = world.hasOwnProperty("ce") ? world["ce"] : true;
- inst.my_timescale = world.hasOwnProperty("mts") ? world["mts"] : -1;
- inst.blend_mode = world.hasOwnProperty("bm") ? world["bm"] : 0;;
- inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
- if (this.gl)
- cr.setGLBlend(inst, inst.blend_mode, this.gl);
- inst.set_bbox_changed();
- if (world.hasOwnProperty("fx"))
- {
- for (i = 0, len = world["fx"].length; i < len; i++)
- {
- fxindex = type.getEffectIndexByName(world["fx"][i]["name"]);
- if (fxindex < 0)
- continue; // must've gone missing
- inst.active_effect_flags[fxindex] = world["fx"][i]["active"];
- inst.effect_params[fxindex] = world["fx"][i]["params"];
- }
- }
- inst.updateActiveEffects();
- }
- obehs = o["behs"];
- if (obehs)
- {
- for (p in obehs)
- {
- if (obehs.hasOwnProperty(p))
- {
- behindex = this.getBehaviorIndexBySid(inst, parseInt(p, 10));
- if (behindex < 0)
- continue; // must've gone missing
- inst.behavior_insts[behindex].loadFromJSON(obehs[p]);
- }
- }
- }
- if (o["data"])
- inst.loadFromJSON(o["data"]);
- };
- Runtime.prototype.fetchLocalFileViaCordova = function (filename, successCallback, errorCallback)
- {
- var path = cordova["file"]["applicationDirectory"] + "www/" + filename;
- window["resolveLocalFileSystemURL"](path, function (entry)
- {
- entry.file(successCallback, errorCallback);
- }, errorCallback);
- };
- Runtime.prototype.fetchLocalFileViaCordovaAsText = function (filename, successCallback, errorCallback)
- {
- this.fetchLocalFileViaCordova(filename, function (file)
- {
- var reader = new FileReader();
- reader.onload = function (e)
- {
- successCallback(e.target.result);
- };
- reader.onerror = errorCallback;
- reader.readAsText(file);
- }, errorCallback);
- };
- var queuedArrayBufferReads = [];
- var activeArrayBufferReads = 0;
- var MAX_ARRAYBUFFER_READS = 8;
- Runtime.prototype.maybeStartNextArrayBufferRead = function()
- {
- if (!queuedArrayBufferReads.length)
- return; // none left
- if (activeArrayBufferReads >= MAX_ARRAYBUFFER_READS)
- return; // already got maximum number in-flight
- activeArrayBufferReads++;
- var job = queuedArrayBufferReads.shift();
- this.doFetchLocalFileViaCordovaAsArrayBuffer(job.filename, job.successCallback, job.errorCallback);
- };
- Runtime.prototype.fetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback_, errorCallback_)
- {
- var self = this;
- queuedArrayBufferReads.push({
- filename: filename,
- successCallback: function (result)
- {
- activeArrayBufferReads--;
- self.maybeStartNextArrayBufferRead();
- successCallback_(result);
- },
- errorCallback: function (err)
- {
- activeArrayBufferReads--;
- self.maybeStartNextArrayBufferRead();
- errorCallback_(err);
- }
- });
- this.maybeStartNextArrayBufferRead();
- };
- Runtime.prototype.doFetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback, errorCallback)
- {
- this.fetchLocalFileViaCordova(filename, function (file)
- {
- var reader = new FileReader();
- reader.onload = function (e)
- {
- successCallback(e.target.result);
- };
- reader.readAsArrayBuffer(file);
- }, errorCallback);
- };
- Runtime.prototype.fetchLocalFileViaCordovaAsURL = function (filename, successCallback, errorCallback)
- {
- var blobType = "";
- var lowername = filename.toLowerCase();
- var ext3 = lowername.substr(lowername.length - 4);
- var ext4 = lowername.substr(lowername.length - 5);
- if (ext3 === ".mp4")
- blobType = "video/mp4";
- else if (ext4 === ".webm")
- blobType = "video/webm"; // use video type but hopefully works with audio too
- else if (ext3 === ".m4a")
- blobType = "audio/mp4";
- else if (ext3 === ".mp3")
- blobType = "audio/mpeg";
- this.fetchLocalFileViaCordovaAsArrayBuffer(filename, function (arrayBuffer)
- {
- var blob = new Blob([arrayBuffer], { type: blobType });
- var url = URL.createObjectURL(blob);
- successCallback(url);
- }, errorCallback);
- };
- Runtime.prototype.isAbsoluteUrl = function (url)
- {
- return /^(?:[a-z]+:)?\/\//.test(url) || url.substr(0, 5) === "data:" || url.substr(0, 5) === "blob:";
- };
- Runtime.prototype.setImageSrc = function (img, src)
- {
- if (this.isWKWebView && !this.isAbsoluteUrl(src))
- {
- this.fetchLocalFileViaCordovaAsURL(src, function (url)
- {
- img.src = url;
- }, function (err)
- {
- alert("Failed to load image: " + err);
- });
- }
- else
- {
- img.src = src;
- }
- };
- Runtime.prototype.setCtxImageSmoothingEnabled = function (ctx, e)
- {
- if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
- {
- ctx["imageSmoothingEnabled"] = e;
- }
- else
- {
- ctx["webkitImageSmoothingEnabled"] = e;
- ctx["mozImageSmoothingEnabled"] = e;
- ctx["msImageSmoothingEnabled"] = e;
- }
- };
- cr.runtime = Runtime;
- cr.createRuntime = function (canvasid)
- {
- return new Runtime(document.getElementById(canvasid));
- };
- cr.createDCRuntime = function (w, h)
- {
- return new Runtime({ "dc": true, "width": w, "height": h });
- };
- window["cr_createRuntime"] = cr.createRuntime;
- window["cr_createDCRuntime"] = cr.createDCRuntime;
- window["createCocoonJSRuntime"] = function ()
- {
- window["c2cocoonjs"] = true;
- var canvas = document.createElement("screencanvas") || document.createElement("canvas");
- canvas.screencanvas = true;
- document.body.appendChild(canvas);
- var rt = new Runtime(canvas);
- window["c2runtime"] = rt;
- window.addEventListener("orientationchange", function () {
- window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
- });
- window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
- return rt;
- };
- window["createEjectaRuntime"] = function ()
- {
- var canvas = document.getElementById("canvas");
- var rt = new Runtime(canvas);
- window["c2runtime"] = rt;
- window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
- return rt;
- };
-}());
-window["cr_getC2Runtime"] = function()
-{
- var canvas = document.getElementById("c2canvas");
- if (canvas)
- return canvas["c2runtime"];
- else if (window["c2runtime"])
- return window["c2runtime"];
- else
- return null;
-}
-window["cr_getSnapshot"] = function (format_, quality_)
-{
- var runtime = window["cr_getC2Runtime"]();
- if (runtime)
- runtime.doCanvasSnapshot(format_, quality_);
-}
-window["cr_sizeCanvas"] = function(w, h)
-{
- if (w === 0 || h === 0)
- return;
- var runtime = window["cr_getC2Runtime"]();
- if (runtime)
- runtime["setSize"](w, h);
-}
-window["cr_setSuspended"] = function(s)
-{
- var runtime = window["cr_getC2Runtime"]();
- if (runtime)
- runtime["setSuspended"](s);
-}
-;
-(function()
-{
- function Layout(runtime, m)
- {
- this.runtime = runtime;
- this.event_sheet = null;
- this.scrollX = (this.runtime.original_width / 2);
- this.scrollY = (this.runtime.original_height / 2);
- this.scale = 1.0;
- this.angle = 0;
- this.first_visit = true;
- this.name = m[0];
- this.originalWidth = m[1];
- this.originalHeight = m[2];
- this.width = m[1];
- this.height = m[2];
- this.unbounded_scrolling = m[3];
- this.sheetname = m[4];
- this.sid = m[5];
- var lm = m[6];
- var i, len;
- this.layers = [];
- this.initial_types = [];
- for (i = 0, len = lm.length; i < len; i++)
- {
- var layer = new cr.layer(this, lm[i]);
- layer.number = i;
- cr.seal(layer);
- this.layers.push(layer);
- }
- var im = m[7];
- this.initial_nonworld = [];
- for (i = 0, len = im.length; i < len; i++)
- {
- var inst = im[i];
- var type = this.runtime.types_by_index[inst[1]];
-;
- if (!type.default_instance)
- type.default_instance = inst;
- this.initial_nonworld.push(inst);
- if (this.initial_types.indexOf(type) === -1)
- this.initial_types.push(type);
- }
- this.effect_types = [];
- this.active_effect_types = [];
- this.shaders_preserve_opaqueness = true;
- this.effect_params = [];
- for (i = 0, len = m[8].length; i < len; i++)
- {
- this.effect_types.push({
- id: m[8][i][0],
- name: m[8][i][1],
- shaderindex: -1,
- preservesOpaqueness: false,
- active: true,
- index: i
- });
- this.effect_params.push(m[8][i][2].slice(0));
- }
- this.updateActiveEffects();
- this.rcTex = new cr.rect(0, 0, 1, 1);
- this.rcTex2 = new cr.rect(0, 0, 1, 1);
- this.persist_data = {};
- };
- Layout.prototype.saveObjectToPersist = function (inst)
- {
- var sidStr = inst.type.sid.toString();
- if (!this.persist_data.hasOwnProperty(sidStr))
- this.persist_data[sidStr] = [];
- var type_persist = this.persist_data[sidStr];
- type_persist.push(this.runtime.saveInstanceToJSON(inst));
- };
- Layout.prototype.hasOpaqueBottomLayer = function ()
- {
- var layer = this.layers[0];
- return !layer.transparent && layer.opacity === 1.0 && !layer.forceOwnTexture && layer.visible;
- };
- Layout.prototype.updateActiveEffects = function ()
- {
- cr.clearArray(this.active_effect_types);
- this.shaders_preserve_opaqueness = true;
- var i, len, et;
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- if (et.active)
- {
- this.active_effect_types.push(et);
- if (!et.preservesOpaqueness)
- this.shaders_preserve_opaqueness = false;
- }
- }
- };
- Layout.prototype.getEffectByName = function (name_)
- {
- var i, len, et;
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- if (et.name === name_)
- return et;
- }
- return null;
- };
- var created_instances = [];
- function sort_by_zindex(a, b)
- {
- return a.zindex - b.zindex;
- };
- var first_layout = true;
- Layout.prototype.startRunning = function ()
- {
- if (this.sheetname)
- {
- this.event_sheet = this.runtime.eventsheets[this.sheetname];
-;
- this.event_sheet.updateDeepIncludes();
- }
- this.runtime.running_layout = this;
- this.width = this.originalWidth;
- this.height = this.originalHeight;
- this.scrollX = (this.runtime.original_width / 2);
- this.scrollY = (this.runtime.original_height / 2);
- var i, k, len, lenk, type, type_instances, initial_inst, inst, iid, t, s, p, q, type_data, layer;
- for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
- {
- type = this.runtime.types_by_index[i];
- if (type.is_family)
- continue; // instances are only transferred for their real type
- type_instances = type.instances;
- for (k = 0, lenk = type_instances.length; k < lenk; k++)
- {
- inst = type_instances[k];
- if (inst.layer)
- {
- var num = inst.layer.number;
- if (num >= this.layers.length)
- num = this.layers.length - 1;
- inst.layer = this.layers[num];
- if (inst.layer.instances.indexOf(inst) === -1)
- inst.layer.instances.push(inst);
- inst.layer.zindices_stale = true;
- }
- }
- }
- if (!first_layout)
- {
- for (i = 0, len = this.layers.length; i < len; ++i)
- {
- this.layers[i].instances.sort(sort_by_zindex);
- }
- }
- var layer;
- cr.clearArray(created_instances);
- this.boundScrolling();
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- layer = this.layers[i];
- layer.createInitialInstances(); // fills created_instances
- layer.updateViewport(null);
- }
- var uids_changed = false;
- if (!this.first_visit)
- {
- for (p in this.persist_data)
- {
- if (this.persist_data.hasOwnProperty(p))
- {
- type = this.runtime.getObjectTypeBySid(parseInt(p, 10));
- if (!type || type.is_family || !this.runtime.typeHasPersistBehavior(type))
- continue;
- type_data = this.persist_data[p];
- for (i = 0, len = type_data.length; i < len; i++)
- {
- layer = null;
- if (type.plugin.is_world)
- {
- layer = this.getLayerBySid(type_data[i]["w"]["l"]);
- if (!layer)
- continue;
- }
- inst = this.runtime.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
- this.runtime.loadInstanceFromJSON(inst, type_data[i]);
- uids_changed = true;
- created_instances.push(inst);
- }
- cr.clearArray(type_data);
- }
- }
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- this.layers[i].instances.sort(sort_by_zindex);
- this.layers[i].zindices_stale = true; // in case of duplicates/holes
- }
- }
- if (uids_changed)
- {
- this.runtime.ClearDeathRow();
- this.runtime.refreshUidMap();
- }
- for (i = 0; i < created_instances.length; i++)
- {
- inst = created_instances[i];
- if (!inst.type.is_contained)
- continue;
- iid = inst.get_iid();
- for (k = 0, lenk = inst.type.container.length; k < lenk; k++)
- {
- t = inst.type.container[k];
- if (inst.type === t)
- continue;
- if (t.instances.length > iid)
- inst.siblings.push(t.instances[iid]);
- else
- {
- if (!t.default_instance)
- {
- }
- else
- {
- s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true);
- this.runtime.ClearDeathRow();
- t.updateIIDs();
- inst.siblings.push(s);
- created_instances.push(s); // come back around and link up its own instances too
- }
- }
- }
- }
- for (i = 0, len = this.initial_nonworld.length; i < len; i++)
- {
- initial_inst = this.initial_nonworld[i];
- type = this.runtime.types_by_index[initial_inst[1]];
- if (!type.is_contained)
- {
- inst = this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true);
- }
-;
- }
- this.runtime.changelayout = null;
- this.runtime.ClearDeathRow();
- if (this.runtime.ctx && !this.runtime.isDomFree)
- {
- for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
- {
- t = this.runtime.types_by_index[i];
- if (t.is_family || !t.instances.length || !t.preloadCanvas2D)
- continue;
- t.preloadCanvas2D(this.runtime.ctx);
- }
- }
- /*
- if (this.runtime.glwrap)
- {
- console.log("Estimated VRAM at layout start: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
- }
- */
- if (this.runtime.isLoadingState)
- {
- cr.shallowAssignArray(this.runtime.fireOnCreateAfterLoad, created_instances);
- }
- else
- {
- for (i = 0, len = created_instances.length; i < len; i++)
- {
- inst = created_instances[i];
- this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
- }
- }
- cr.clearArray(created_instances);
- if (!this.runtime.isLoadingState)
- {
- this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null);
- }
- this.first_visit = false;
- };
- Layout.prototype.createGlobalNonWorlds = function ()
- {
- var i, k, len, initial_inst, inst, type;
- for (i = 0, k = 0, len = this.initial_nonworld.length; i < len; i++)
- {
- initial_inst = this.initial_nonworld[i];
- type = this.runtime.types_by_index[initial_inst[1]];
- if (type.global)
- {
- if (!type.is_contained)
- {
- inst = this.runtime.createInstanceFromInit(initial_inst, null, true);
- }
- }
- else
- {
- this.initial_nonworld[k] = initial_inst;
- k++;
- }
- }
- cr.truncateArray(this.initial_nonworld, k);
- };
- Layout.prototype.stopRunning = function ()
- {
-;
- /*
- if (this.runtime.glwrap)
- {
- console.log("Estimated VRAM at layout end: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
- }
- */
- if (!this.runtime.isLoadingState)
- {
- this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutEnd, null);
- }
- this.runtime.isEndingLayout = true;
- cr.clearArray(this.runtime.system.waits);
- var i, leni, j, lenj;
- var layer_instances, inst, type;
- if (!this.first_visit)
- {
- for (i = 0, leni = this.layers.length; i < leni; i++)
- {
- this.layers[i].updateZIndices();
- layer_instances = this.layers[i].instances;
- for (j = 0, lenj = layer_instances.length; j < lenj; j++)
- {
- inst = layer_instances[j];
- if (!inst.type.global)
- {
- if (this.runtime.typeHasPersistBehavior(inst.type))
- this.saveObjectToPersist(inst);
- }
- }
- }
- }
- for (i = 0, leni = this.layers.length; i < leni; i++)
- {
- layer_instances = this.layers[i].instances;
- for (j = 0, lenj = layer_instances.length; j < lenj; j++)
- {
- inst = layer_instances[j];
- if (!inst.type.global)
- {
- this.runtime.DestroyInstance(inst);
- }
- }
- this.runtime.ClearDeathRow();
- cr.clearArray(layer_instances);
- this.layers[i].zindices_stale = true;
- }
- for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++)
- {
- type = this.runtime.types_by_index[i];
- if (type.global || type.plugin.is_world || type.plugin.singleglobal || type.is_family)
- continue;
- for (j = 0, lenj = type.instances.length; j < lenj; j++)
- this.runtime.DestroyInstance(type.instances[j]);
- this.runtime.ClearDeathRow();
- }
- first_layout = false;
- this.runtime.isEndingLayout = false;
- };
- var temp_rect = new cr.rect(0, 0, 0, 0);
- Layout.prototype.recreateInitialObjects = function (type, x1, y1, x2, y2)
- {
- temp_rect.set(x1, y1, x2, y2);
- var i, len;
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- this.layers[i].recreateInitialObjects(type, temp_rect);
- }
- };
- Layout.prototype.draw = function (ctx)
- {
- var layout_canvas;
- var layout_ctx = ctx;
- var ctx_changed = false;
- var render_offscreen = !this.runtime.fullscreenScalingQuality;
- if (render_offscreen)
- {
- if (!this.runtime.layout_canvas)
- {
- this.runtime.layout_canvas = document.createElement("canvas");
- layout_canvas = this.runtime.layout_canvas;
- layout_canvas.width = this.runtime.draw_width;
- layout_canvas.height = this.runtime.draw_height;
- this.runtime.layout_ctx = layout_canvas.getContext("2d");
- ctx_changed = true;
- }
- layout_canvas = this.runtime.layout_canvas;
- layout_ctx = this.runtime.layout_ctx;
- if (layout_canvas.width !== this.runtime.draw_width)
- {
- layout_canvas.width = this.runtime.draw_width;
- ctx_changed = true;
- }
- if (layout_canvas.height !== this.runtime.draw_height)
- {
- layout_canvas.height = this.runtime.draw_height;
- ctx_changed = true;
- }
- if (ctx_changed)
- {
- this.runtime.setCtxImageSmoothingEnabled(layout_ctx, this.runtime.linearSampling);
- }
- }
- layout_ctx.globalAlpha = 1;
- layout_ctx.globalCompositeOperation = "source-over";
- if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
- layout_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
- var i, len, l;
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- l = this.layers[i];
- if (l.visible && l.opacity > 0 && l.blend_mode !== 11 && (l.instances.length || !l.transparent))
- l.draw(layout_ctx);
- else
- l.updateViewport(null); // even if not drawing, keep viewport up to date
- }
- if (render_offscreen)
- {
- ctx.drawImage(layout_canvas, 0, 0, this.runtime.width, this.runtime.height);
- }
- };
- Layout.prototype.drawGL_earlyZPass = function (glw)
- {
- glw.setEarlyZPass(true);
- if (!this.runtime.layout_tex)
- {
- this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
- {
- glw.deleteTexture(this.runtime.layout_tex);
- this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- glw.setRenderingToTexture(this.runtime.layout_tex);
- if (!this.runtime.fullscreenScalingQuality)
- {
- glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
- }
- var i, l;
- for (i = this.layers.length - 1; i >= 0; --i)
- {
- l = this.layers[i];
- if (l.visible && l.opacity === 1 && l.shaders_preserve_opaqueness &&
- l.blend_mode === 0 && (l.instances.length || !l.transparent))
- {
- l.drawGL_earlyZPass(glw);
- }
- else
- {
- l.updateViewport(null); // even if not drawing, keep viewport up to date
- }
- }
- glw.setEarlyZPass(false);
- };
- Layout.prototype.drawGL = function (glw)
- {
- var render_to_texture = (this.active_effect_types.length > 0 ||
- this.runtime.uses_background_blending ||
- !this.runtime.fullscreenScalingQuality ||
- this.runtime.enableFrontToBack);
- if (render_to_texture)
- {
- if (!this.runtime.layout_tex)
- {
- this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
- {
- glw.deleteTexture(this.runtime.layout_tex);
- this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- glw.setRenderingToTexture(this.runtime.layout_tex);
- if (!this.runtime.fullscreenScalingQuality)
- {
- glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
- }
- }
- else
- {
- if (this.runtime.layout_tex)
- {
- glw.setRenderingToTexture(null);
- glw.deleteTexture(this.runtime.layout_tex);
- this.runtime.layout_tex = null;
- }
- }
- if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
- glw.clear(0, 0, 0, 0);
- var i, len, l;
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- l = this.layers[i];
- if (l.visible && l.opacity > 0 && (l.instances.length || !l.transparent))
- l.drawGL(glw);
- else
- l.updateViewport(null); // even if not drawing, keep viewport up to date
- }
- if (render_to_texture)
- {
- if (this.active_effect_types.length === 0 ||
- (this.active_effect_types.length === 1 && this.runtime.fullscreenScalingQuality))
- {
- if (this.active_effect_types.length === 1)
- {
- var etindex = this.active_effect_types[0].index;
- glw.switchProgram(this.active_effect_types[0].shaderindex);
- glw.setProgramParameters(null, // backTex
- 1.0 / this.runtime.draw_width, // pixelWidth
- 1.0 / this.runtime.draw_height, // pixelHeight
- 0.0, 0.0, // destStart
- 1.0, 1.0, // destEnd
- this.scale, // layerScale
- this.angle, // layerAngle
- 0.0, 0.0, // viewOrigin
- this.runtime.draw_width / 2, this.runtime.draw_height / 2, // scrollPos
- this.runtime.kahanTime.sum, // seconds
- this.effect_params[etindex]); // fx parameters
- if (glw.programIsAnimated(this.active_effect_types[0].shaderindex))
- this.runtime.redraw = true;
- }
- else
- glw.switchProgram(0);
- if (!this.runtime.fullscreenScalingQuality)
- {
- glw.setSize(this.runtime.width, this.runtime.height);
- }
- glw.setRenderingToTexture(null); // to backbuffer
- glw.setDepthTestEnabled(false); // ignore depth buffer, copy full texture
- glw.setOpacity(1);
- glw.setTexture(this.runtime.layout_tex);
- glw.setAlphaBlend();
- glw.resetModelView();
- glw.updateModelView();
- var halfw = this.runtime.width / 2;
- var halfh = this.runtime.height / 2;
- glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
- glw.setTexture(null);
- glw.setDepthTestEnabled(true); // turn depth test back on
- }
- else
- {
- this.renderEffectChain(glw, null, null, null);
- }
- }
- };
- Layout.prototype.getRenderTarget = function()
- {
- if (this.active_effect_types.length > 0 ||
- this.runtime.uses_background_blending ||
- !this.runtime.fullscreenScalingQuality ||
- this.runtime.enableFrontToBack)
- {
- return this.runtime.layout_tex;
- }
- else
- {
- return null;
- }
- };
- Layout.prototype.getMinLayerScale = function ()
- {
- var m = this.layers[0].getScale();
- var i, len, l;
- for (i = 1, len = this.layers.length; i < len; i++)
- {
- l = this.layers[i];
- if (l.parallaxX === 0 && l.parallaxY === 0)
- continue;
- if (l.getScale() < m)
- m = l.getScale();
- }
- return m;
- };
- Layout.prototype.scrollToX = function (x)
- {
- if (!this.unbounded_scrolling)
- {
- var widthBoundary = (this.runtime.draw_width * (1 / this.getMinLayerScale()) / 2);
- if (x > this.width - widthBoundary)
- x = this.width - widthBoundary;
- if (x < widthBoundary)
- x = widthBoundary;
- }
- if (this.scrollX !== x)
- {
- this.scrollX = x;
- this.runtime.redraw = true;
- }
- };
- Layout.prototype.scrollToY = function (y)
- {
- if (!this.unbounded_scrolling)
- {
- var heightBoundary = (this.runtime.draw_height * (1 / this.getMinLayerScale()) / 2);
- if (y > this.height - heightBoundary)
- y = this.height - heightBoundary;
- if (y < heightBoundary)
- y = heightBoundary;
- }
- if (this.scrollY !== y)
- {
- this.scrollY = y;
- this.runtime.redraw = true;
- }
- };
- Layout.prototype.boundScrolling = function ()
- {
- this.scrollToX(this.scrollX);
- this.scrollToY(this.scrollY);
- };
- Layout.prototype.renderEffectChain = function (glw, layer, inst, rendertarget)
- {
- var active_effect_types = inst ?
- inst.active_effect_types :
- layer ?
- layer.active_effect_types :
- this.active_effect_types;
- var layerScale = 1, layerAngle = 0, viewOriginLeft = 0, viewOriginTop = 0, viewOriginRight = this.runtime.draw_width, viewOriginBottom = this.runtime.draw_height;
- if (inst)
- {
- layerScale = inst.layer.getScale();
- layerAngle = inst.layer.getAngle();
- viewOriginLeft = inst.layer.viewLeft;
- viewOriginTop = inst.layer.viewTop;
- viewOriginRight = inst.layer.viewRight;
- viewOriginBottom = inst.layer.viewBottom;
- }
- else if (layer)
- {
- layerScale = layer.getScale();
- layerAngle = layer.getAngle();
- viewOriginLeft = layer.viewLeft;
- viewOriginTop = layer.viewTop;
- viewOriginRight = layer.viewRight;
- viewOriginBottom = layer.viewBottom;
- }
- var fx_tex = this.runtime.fx_tex;
- var i, len, last, temp, fx_index = 0, other_fx_index = 1;
- var y, h;
- var windowWidth = this.runtime.draw_width;
- var windowHeight = this.runtime.draw_height;
- var halfw = windowWidth / 2;
- var halfh = windowHeight / 2;
- var rcTex = layer ? layer.rcTex : this.rcTex;
- var rcTex2 = layer ? layer.rcTex2 : this.rcTex2;
- var screenleft = 0, clearleft = 0;
- var screentop = 0, cleartop = 0;
- var screenright = windowWidth, clearright = windowWidth;
- var screenbottom = windowHeight, clearbottom = windowHeight;
- var boxExtendHorizontal = 0;
- var boxExtendVertical = 0;
- var inst_layer_angle = inst ? inst.layer.getAngle() : 0;
- if (inst)
- {
- for (i = 0, len = active_effect_types.length; i < len; i++)
- {
- boxExtendHorizontal += glw.getProgramBoxExtendHorizontal(active_effect_types[i].shaderindex);
- boxExtendVertical += glw.getProgramBoxExtendVertical(active_effect_types[i].shaderindex);
- }
- var bbox = inst.bbox;
- screenleft = layer.layerToCanvas(bbox.left, bbox.top, true, true);
- screentop = layer.layerToCanvas(bbox.left, bbox.top, false, true);
- screenright = layer.layerToCanvas(bbox.right, bbox.bottom, true, true);
- screenbottom = layer.layerToCanvas(bbox.right, bbox.bottom, false, true);
- if (inst_layer_angle !== 0)
- {
- var screentrx = layer.layerToCanvas(bbox.right, bbox.top, true, true);
- var screentry = layer.layerToCanvas(bbox.right, bbox.top, false, true);
- var screenblx = layer.layerToCanvas(bbox.left, bbox.bottom, true, true);
- var screenbly = layer.layerToCanvas(bbox.left, bbox.bottom, false, true);
- temp = Math.min(screenleft, screenright, screentrx, screenblx);
- screenright = Math.max(screenleft, screenright, screentrx, screenblx);
- screenleft = temp;
- temp = Math.min(screentop, screenbottom, screentry, screenbly);
- screenbottom = Math.max(screentop, screenbottom, screentry, screenbly);
- screentop = temp;
- }
- screenleft -= boxExtendHorizontal;
- screentop -= boxExtendVertical;
- screenright += boxExtendHorizontal;
- screenbottom += boxExtendVertical;
- rcTex2.left = screenleft / windowWidth;
- rcTex2.top = 1 - screentop / windowHeight;
- rcTex2.right = screenright / windowWidth;
- rcTex2.bottom = 1 - screenbottom / windowHeight;
- clearleft = screenleft = cr.floor(screenleft);
- cleartop = screentop = cr.floor(screentop);
- clearright = screenright = cr.ceil(screenright);
- clearbottom = screenbottom = cr.ceil(screenbottom);
- clearleft -= boxExtendHorizontal;
- cleartop -= boxExtendVertical;
- clearright += boxExtendHorizontal;
- clearbottom += boxExtendVertical;
- if (screenleft < 0) screenleft = 0;
- if (screentop < 0) screentop = 0;
- if (screenright > windowWidth) screenright = windowWidth;
- if (screenbottom > windowHeight) screenbottom = windowHeight;
- if (clearleft < 0) clearleft = 0;
- if (cleartop < 0) cleartop = 0;
- if (clearright > windowWidth) clearright = windowWidth;
- if (clearbottom > windowHeight) clearbottom = windowHeight;
- rcTex.left = screenleft / windowWidth;
- rcTex.top = 1 - screentop / windowHeight;
- rcTex.right = screenright / windowWidth;
- rcTex.bottom = 1 - screenbottom / windowHeight;
- }
- else
- {
- rcTex.left = rcTex2.left = 0;
- rcTex.top = rcTex2.top = 0;
- rcTex.right = rcTex2.right = 1;
- rcTex.bottom = rcTex2.bottom = 1;
- }
- var pre_draw = (inst && (glw.programUsesDest(active_effect_types[0].shaderindex) || boxExtendHorizontal !== 0 || boxExtendVertical !== 0 || inst.opacity !== 1 || inst.type.plugin.must_predraw)) || (layer && !inst && layer.opacity !== 1);
- glw.setAlphaBlend();
- if (pre_draw)
- {
- if (!fx_tex[fx_index])
- {
- fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
- }
- if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
- {
- glw.deleteTexture(fx_tex[fx_index]);
- fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
- }
- glw.switchProgram(0);
- glw.setRenderingToTexture(fx_tex[fx_index]);
- h = clearbottom - cleartop;
- y = (windowHeight - cleartop) - h;
- glw.clearRect(clearleft, y, clearright - clearleft, h);
- if (inst)
- {
- inst.drawGL(glw);
- }
- else
- {
- glw.setTexture(this.runtime.layer_tex);
- glw.setOpacity(layer.opacity);
- glw.resetModelView();
- glw.translate(-halfw, -halfh);
- glw.updateModelView();
- glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
- }
- rcTex2.left = rcTex2.top = 0;
- rcTex2.right = rcTex2.bottom = 1;
- if (inst)
- {
- temp = rcTex.top;
- rcTex.top = rcTex.bottom;
- rcTex.bottom = temp;
- }
- fx_index = 1;
- other_fx_index = 0;
- }
- glw.setOpacity(1);
- var last = active_effect_types.length - 1;
- var post_draw = glw.programUsesCrossSampling(active_effect_types[last].shaderindex) ||
- (!layer && !inst && !this.runtime.fullscreenScalingQuality);
- var etindex = 0;
- for (i = 0, len = active_effect_types.length; i < len; i++)
- {
- if (!fx_tex[fx_index])
- {
- fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
- }
- if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
- {
- glw.deleteTexture(fx_tex[fx_index]);
- fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
- }
- glw.switchProgram(active_effect_types[i].shaderindex);
- etindex = active_effect_types[i].index;
- if (glw.programIsAnimated(active_effect_types[i].shaderindex))
- this.runtime.redraw = true;
- if (i == 0 && !pre_draw)
- {
- glw.setRenderingToTexture(fx_tex[fx_index]);
- h = clearbottom - cleartop;
- y = (windowHeight - cleartop) - h;
- glw.clearRect(clearleft, y, clearright - clearleft, h);
- if (inst)
- {
- var pixelWidth;
- var pixelHeight;
- if (inst.curFrame && inst.curFrame.texture_img)
- {
- var img = inst.curFrame.texture_img;
- pixelWidth = 1.0 / img.width;
- pixelHeight = 1.0 / img.height;
- }
- else
- {
- pixelWidth = 1.0 / inst.width;
- pixelHeight = 1.0 / inst.height;
- }
- glw.setProgramParameters(rendertarget, // backTex
- pixelWidth,
- pixelHeight,
- rcTex2.left, rcTex2.top, // destStart
- rcTex2.right, rcTex2.bottom, // destEnd
- layerScale,
- layerAngle,
- viewOriginLeft, viewOriginTop,
- (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
- this.runtime.kahanTime.sum,
- inst.effect_params[etindex]); // fx params
- inst.drawGL(glw);
- }
- else
- {
- glw.setProgramParameters(rendertarget, // backTex
- 1.0 / windowWidth, // pixelWidth
- 1.0 / windowHeight, // pixelHeight
- 0.0, 0.0, // destStart
- 1.0, 1.0, // destEnd
- layerScale,
- layerAngle,
- viewOriginLeft, viewOriginTop,
- (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
- this.runtime.kahanTime.sum,
- layer ? // fx params
- layer.effect_params[etindex] :
- this.effect_params[etindex]);
- glw.setTexture(layer ? this.runtime.layer_tex : this.runtime.layout_tex);
- glw.resetModelView();
- glw.translate(-halfw, -halfh);
- glw.updateModelView();
- glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
- }
- rcTex2.left = rcTex2.top = 0;
- rcTex2.right = rcTex2.bottom = 1;
- if (inst && !post_draw)
- {
- temp = screenbottom;
- screenbottom = screentop;
- screentop = temp;
- }
- }
- else
- {
- glw.setProgramParameters(rendertarget, // backTex
- 1.0 / windowWidth, // pixelWidth
- 1.0 / windowHeight, // pixelHeight
- rcTex2.left, rcTex2.top, // destStart
- rcTex2.right, rcTex2.bottom, // destEnd
- layerScale,
- layerAngle,
- viewOriginLeft, viewOriginTop,
- (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
- this.runtime.kahanTime.sum,
- inst ? // fx params
- inst.effect_params[etindex] :
- layer ?
- layer.effect_params[etindex] :
- this.effect_params[etindex]);
- glw.setTexture(null);
- if (i === last && !post_draw)
- {
- if (inst)
- glw.setBlend(inst.srcBlend, inst.destBlend);
- else if (layer)
- glw.setBlend(layer.srcBlend, layer.destBlend);
- glw.setRenderingToTexture(rendertarget);
- }
- else
- {
- glw.setRenderingToTexture(fx_tex[fx_index]);
- h = clearbottom - cleartop;
- y = (windowHeight - cleartop) - h;
- glw.clearRect(clearleft, y, clearright - clearleft, h);
- }
- glw.setTexture(fx_tex[other_fx_index]);
- glw.resetModelView();
- glw.translate(-halfw, -halfh);
- glw.updateModelView();
- glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
- if (i === last && !post_draw)
- glw.setTexture(null);
- }
- fx_index = (fx_index === 0 ? 1 : 0);
- other_fx_index = (fx_index === 0 ? 1 : 0); // will be opposite to fx_index since it was just assigned
- }
- if (post_draw)
- {
- glw.switchProgram(0);
- if (inst)
- glw.setBlend(inst.srcBlend, inst.destBlend);
- else if (layer)
- glw.setBlend(layer.srcBlend, layer.destBlend);
- else
- {
- if (!this.runtime.fullscreenScalingQuality)
- {
- glw.setSize(this.runtime.width, this.runtime.height);
- halfw = this.runtime.width / 2;
- halfh = this.runtime.height / 2;
- screenleft = 0;
- screentop = 0;
- screenright = this.runtime.width;
- screenbottom = this.runtime.height;
- }
- }
- glw.setRenderingToTexture(rendertarget);
- glw.setTexture(fx_tex[other_fx_index]);
- glw.resetModelView();
- glw.translate(-halfw, -halfh);
- glw.updateModelView();
- if (inst && active_effect_types.length === 1 && !pre_draw)
- glw.quadTex(screenleft, screentop, screenright, screentop, screenright, screenbottom, screenleft, screenbottom, rcTex);
- else
- glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
- glw.setTexture(null);
- }
- };
- Layout.prototype.getLayerBySid = function (sid_)
- {
- var i, len;
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- if (this.layers[i].sid === sid_)
- return this.layers[i];
- }
- return null;
- };
- Layout.prototype.saveToJSON = function ()
- {
- var i, len, layer, et;
- var o = {
- "sx": this.scrollX,
- "sy": this.scrollY,
- "s": this.scale,
- "a": this.angle,
- "w": this.width,
- "h": this.height,
- "fv": this.first_visit, // added r127
- "persist": this.persist_data,
- "fx": [],
- "layers": {}
- };
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
- }
- for (i = 0, len = this.layers.length; i < len; i++)
- {
- layer = this.layers[i];
- o["layers"][layer.sid.toString()] = layer.saveToJSON();
- }
- return o;
- };
- Layout.prototype.loadFromJSON = function (o)
- {
- var i, j, len, fx, p, layer;
- this.scrollX = o["sx"];
- this.scrollY = o["sy"];
- this.scale = o["s"];
- this.angle = o["a"];
- this.width = o["w"];
- this.height = o["h"];
- this.persist_data = o["persist"];
- if (typeof o["fv"] !== "undefined")
- this.first_visit = o["fv"];
- var ofx = o["fx"];
- for (i = 0, len = ofx.length; i < len; i++)
- {
- fx = this.getEffectByName(ofx[i]["name"]);
- if (!fx)
- continue; // must've gone missing
- fx.active = ofx[i]["active"];
- this.effect_params[fx.index] = ofx[i]["params"];
- }
- this.updateActiveEffects();
- var olayers = o["layers"];
- for (p in olayers)
- {
- if (olayers.hasOwnProperty(p))
- {
- layer = this.getLayerBySid(parseInt(p, 10));
- if (!layer)
- continue; // must've gone missing
- layer.loadFromJSON(olayers[p]);
- }
- }
- };
- cr.layout = Layout;
- function Layer(layout, m)
- {
- this.layout = layout;
- this.runtime = layout.runtime;
- this.instances = []; // running instances
- this.scale = 1.0;
- this.angle = 0;
- this.disableAngle = false;
- this.tmprect = new cr.rect(0, 0, 0, 0);
- this.tmpquad = new cr.quad();
- this.viewLeft = 0;
- this.viewRight = 0;
- this.viewTop = 0;
- this.viewBottom = 0;
- this.zindices_stale = false;
- this.zindices_stale_from = -1; // first index that has changed, or -1 if no bound
- this.clear_earlyz_index = 0;
- this.name = m[0];
- this.index = m[1];
- this.sid = m[2];
- this.visible = m[3]; // initially visible
- this.background_color = m[4];
- this.transparent = m[5];
- this.parallaxX = m[6];
- this.parallaxY = m[7];
- this.opacity = m[8];
- this.forceOwnTexture = m[9];
- this.useRenderCells = m[10];
- this.zoomRate = m[11];
- this.blend_mode = m[12];
- this.effect_fallback = m[13];
- this.compositeOp = "source-over";
- this.srcBlend = 0;
- this.destBlend = 0;
- this.render_grid = null;
- this.last_render_list = alloc_arr();
- this.render_list_stale = true;
- this.last_render_cells = new cr.rect(0, 0, -1, -1);
- this.cur_render_cells = new cr.rect(0, 0, -1, -1);
- if (this.useRenderCells)
- {
- this.render_grid = new cr.RenderGrid(this.runtime.original_width, this.runtime.original_height);
- }
- this.render_offscreen = false;
- var im = m[14];
- var i, len;
- this.startup_initial_instances = []; // for restoring initial_instances after load
- this.initial_instances = [];
- this.created_globals = []; // global object UIDs already created - for save/load to avoid recreating
- for (i = 0, len = im.length; i < len; i++)
- {
- var inst = im[i];
- var type = this.runtime.types_by_index[inst[1]];
-;
- if (!type.default_instance)
- {
- type.default_instance = inst;
- type.default_layerindex = this.index;
- }
- this.initial_instances.push(inst);
- if (this.layout.initial_types.indexOf(type) === -1)
- this.layout.initial_types.push(type);
- }
- cr.shallowAssignArray(this.startup_initial_instances, this.initial_instances);
- this.effect_types = [];
- this.active_effect_types = [];
- this.shaders_preserve_opaqueness = true;
- this.effect_params = [];
- for (i = 0, len = m[15].length; i < len; i++)
- {
- this.effect_types.push({
- id: m[15][i][0],
- name: m[15][i][1],
- shaderindex: -1,
- preservesOpaqueness: false,
- active: true,
- index: i
- });
- this.effect_params.push(m[15][i][2].slice(0));
- }
- this.updateActiveEffects();
- this.rcTex = new cr.rect(0, 0, 1, 1);
- this.rcTex2 = new cr.rect(0, 0, 1, 1);
- };
- Layer.prototype.updateActiveEffects = function ()
- {
- cr.clearArray(this.active_effect_types);
- this.shaders_preserve_opaqueness = true;
- var i, len, et;
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- if (et.active)
- {
- this.active_effect_types.push(et);
- if (!et.preservesOpaqueness)
- this.shaders_preserve_opaqueness = false;
- }
- }
- };
- Layer.prototype.getEffectByName = function (name_)
- {
- var i, len, et;
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- if (et.name === name_)
- return et;
- }
- return null;
- };
- Layer.prototype.createInitialInstances = function ()
- {
- var i, k, len, inst, initial_inst, type, keep, hasPersistBehavior;
- for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++)
- {
- initial_inst = this.initial_instances[i];
- type = this.runtime.types_by_index[initial_inst[1]];
-;
- hasPersistBehavior = this.runtime.typeHasPersistBehavior(type);
- keep = true;
- if (!hasPersistBehavior || this.layout.first_visit)
- {
- inst = this.runtime.createInstanceFromInit(initial_inst, this, true);
- if (!inst)
- continue; // may have skipped creation due to fallback effect "destroy"
- created_instances.push(inst);
- if (inst.type.global)
- {
- keep = false;
- this.created_globals.push(inst.uid);
- }
- }
- if (keep)
- {
- this.initial_instances[k] = this.initial_instances[i];
- k++;
- }
- }
- this.initial_instances.length = k;
- this.runtime.ClearDeathRow(); // flushes creation row so IIDs will be correct
- if (!this.runtime.glwrap && this.effect_types.length) // no WebGL renderer and shaders used
- this.blend_mode = this.effect_fallback; // use fallback blend mode
- this.compositeOp = cr.effectToCompositeOp(this.blend_mode);
- if (this.runtime.gl)
- cr.setGLBlend(this, this.blend_mode, this.runtime.gl);
- this.render_list_stale = true;
- };
- Layer.prototype.recreateInitialObjects = function (only_type, rc)
- {
- var i, len, initial_inst, type, wm, x, y, inst, j, lenj, s;
- var types_by_index = this.runtime.types_by_index;
- var only_type_is_family = only_type.is_family;
- var only_type_members = only_type.members;
- for (i = 0, len = this.initial_instances.length; i < len; ++i)
- {
- initial_inst = this.initial_instances[i];
- wm = initial_inst[0];
- x = wm[0];
- y = wm[1];
- if (!rc.contains_pt(x, y))
- continue; // not in the given area
- type = types_by_index[initial_inst[1]];
- if (type !== only_type)
- {
- if (only_type_is_family)
- {
- if (only_type_members.indexOf(type) < 0)
- continue;
- }
- else
- continue; // only_type is not a family, and the initial inst type does not match
- }
- inst = this.runtime.createInstanceFromInit(initial_inst, this, false);
- this.runtime.isInOnDestroy++;
- this.runtime.trigger(Object.getPrototypeOf(type.plugin).cnds.OnCreated, inst);
- if (inst.is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[i];
- this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
- }
- }
- this.runtime.isInOnDestroy--;
- }
- };
- Layer.prototype.removeFromInstanceList = function (inst, remove_from_grid)
- {
- var index = cr.fastIndexOf(this.instances, inst);
- if (index < 0)
- return; // not found
- if (remove_from_grid && this.useRenderCells && inst.rendercells && inst.rendercells.right >= inst.rendercells.left)
- {
- inst.update_bbox(); // make sure actually in its current rendercells
- this.render_grid.update(inst, inst.rendercells, null); // no new range provided - remove only
- inst.rendercells.set(0, 0, -1, -1); // set to invalid state to indicate not inserted
- }
- if (index === this.instances.length - 1)
- this.instances.pop();
- else
- {
- cr.arrayRemove(this.instances, index);
- this.setZIndicesStaleFrom(index);
- }
- this.render_list_stale = true;
- };
- Layer.prototype.appendToInstanceList = function (inst, add_to_grid)
- {
-;
- inst.zindex = this.instances.length;
- this.instances.push(inst);
- if (add_to_grid && this.useRenderCells && inst.rendercells)
- {
- inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
- }
- this.render_list_stale = true;
- };
- Layer.prototype.prependToInstanceList = function (inst, add_to_grid)
- {
-;
- this.instances.unshift(inst);
- this.setZIndicesStaleFrom(0);
- if (add_to_grid && this.useRenderCells && inst.rendercells)
- {
- inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
- }
- };
- Layer.prototype.moveInstanceAdjacent = function (inst, other, isafter)
- {
-;
- var myZ = inst.get_zindex();
- var insertZ = other.get_zindex();
- cr.arrayRemove(this.instances, myZ);
- if (myZ < insertZ)
- insertZ--;
- if (isafter)
- insertZ++;
- if (insertZ === this.instances.length)
- this.instances.push(inst);
- else
- this.instances.splice(insertZ, 0, inst);
- this.setZIndicesStaleFrom(myZ < insertZ ? myZ : insertZ);
- };
- Layer.prototype.setZIndicesStaleFrom = function (index)
- {
- if (this.zindices_stale_from === -1) // not yet set
- this.zindices_stale_from = index;
- else if (index < this.zindices_stale_from) // determine minimum z index affected
- this.zindices_stale_from = index;
- this.zindices_stale = true;
- this.render_list_stale = true;
- };
- Layer.prototype.updateZIndices = function ()
- {
- if (!this.zindices_stale)
- return;
- if (this.zindices_stale_from === -1)
- this.zindices_stale_from = 0;
- var i, len, inst;
- if (this.useRenderCells)
- {
- for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
- {
- inst = this.instances[i];
- inst.zindex = i;
- this.render_grid.markRangeChanged(inst.rendercells);
- }
- }
- else
- {
- for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
- {
- this.instances[i].zindex = i;
- }
- }
- this.zindices_stale = false;
- this.zindices_stale_from = -1;
- };
- Layer.prototype.getScale = function (include_aspect)
- {
- return this.getNormalScale() * (this.runtime.fullscreenScalingQuality || include_aspect ? this.runtime.aspect_scale : 1);
- };
- Layer.prototype.getNormalScale = function ()
- {
- return ((this.scale * this.layout.scale) - 1) * this.zoomRate + 1;
- };
- Layer.prototype.getAngle = function ()
- {
- if (this.disableAngle)
- return 0;
- return cr.clamp_angle(this.layout.angle + this.angle);
- };
- var arr_cache = [];
- function alloc_arr()
- {
- if (arr_cache.length)
- return arr_cache.pop();
- else
- return [];
- }
- function free_arr(a)
- {
- cr.clearArray(a);
- arr_cache.push(a);
- };
- function mergeSortedZArrays(a, b, out)
- {
- var i = 0, j = 0, k = 0, lena = a.length, lenb = b.length, ai, bj;
- out.length = lena + lenb;
- for ( ; i < lena && j < lenb; ++k)
- {
- ai = a[i];
- bj = b[j];
- if (ai.zindex < bj.zindex)
- {
- out[k] = ai;
- ++i;
- }
- else
- {
- out[k] = bj;
- ++j;
- }
- }
- for ( ; i < lena; ++i, ++k)
- out[k] = a[i];
- for ( ; j < lenb; ++j, ++k)
- out[k] = b[j];
- };
- var next_arr = [];
- function mergeAllSortedZArrays_pass(arr, first_pass)
- {
- var i, len, arr1, arr2, out;
- for (i = 0, len = arr.length; i < len - 1; i += 2)
- {
- arr1 = arr[i];
- arr2 = arr[i+1];
- out = alloc_arr();
- mergeSortedZArrays(arr1, arr2, out);
- if (!first_pass)
- {
- free_arr(arr1);
- free_arr(arr2);
- }
- next_arr.push(out);
- }
- if (len % 2 === 1)
- {
- if (first_pass)
- {
- arr1 = alloc_arr();
- cr.shallowAssignArray(arr1, arr[len - 1]);
- next_arr.push(arr1);
- }
- else
- {
- next_arr.push(arr[len - 1]);
- }
- }
- cr.shallowAssignArray(arr, next_arr);
- cr.clearArray(next_arr);
- };
- function mergeAllSortedZArrays(arr)
- {
- var first_pass = true;
- while (arr.length > 1)
- {
- mergeAllSortedZArrays_pass(arr, first_pass);
- first_pass = false;
- }
- return arr[0];
- };
- var render_arr = [];
- Layer.prototype.getRenderCellInstancesToDraw = function ()
- {
-;
- this.updateZIndices();
- this.render_grid.queryRange(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom, render_arr);
- if (!render_arr.length)
- return alloc_arr();
- if (render_arr.length === 1)
- {
- var a = alloc_arr();
- cr.shallowAssignArray(a, render_arr[0]);
- cr.clearArray(render_arr);
- return a;
- }
- var draw_list = mergeAllSortedZArrays(render_arr);
- cr.clearArray(render_arr);
- return draw_list;
- };
- Layer.prototype.draw = function (ctx)
- {
- this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.blend_mode !== 0);
- var layer_canvas = this.runtime.canvas;
- var layer_ctx = ctx;
- var ctx_changed = false;
- if (this.render_offscreen)
- {
- if (!this.runtime.layer_canvas)
- {
- this.runtime.layer_canvas = document.createElement("canvas");
-;
- layer_canvas = this.runtime.layer_canvas;
- layer_canvas.width = this.runtime.draw_width;
- layer_canvas.height = this.runtime.draw_height;
- this.runtime.layer_ctx = layer_canvas.getContext("2d");
-;
- ctx_changed = true;
- }
- layer_canvas = this.runtime.layer_canvas;
- layer_ctx = this.runtime.layer_ctx;
- if (layer_canvas.width !== this.runtime.draw_width)
- {
- layer_canvas.width = this.runtime.draw_width;
- ctx_changed = true;
- }
- if (layer_canvas.height !== this.runtime.draw_height)
- {
- layer_canvas.height = this.runtime.draw_height;
- ctx_changed = true;
- }
- if (ctx_changed)
- {
- this.runtime.setCtxImageSmoothingEnabled(layer_ctx, this.runtime.linearSampling);
- }
- if (this.transparent)
- layer_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
- }
- layer_ctx.globalAlpha = 1;
- layer_ctx.globalCompositeOperation = "source-over";
- if (!this.transparent)
- {
- layer_ctx.fillStyle = "rgb(" + this.background_color[0] + "," + this.background_color[1] + "," + this.background_color[2] + ")";
- layer_ctx.fillRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
- }
- layer_ctx.save();
- this.disableAngle = true;
- var px = this.canvasToLayer(0, 0, true, true);
- var py = this.canvasToLayer(0, 0, false, true);
- this.disableAngle = false;
- if (this.runtime.pixel_rounding)
- {
- px = Math.round(px);
- py = Math.round(py);
- }
- this.rotateViewport(px, py, layer_ctx);
- var myscale = this.getScale();
- layer_ctx.scale(myscale, myscale);
- layer_ctx.translate(-px, -py);
- var instances_to_draw;
- if (this.useRenderCells)
- {
- this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
- this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
- this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
- this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
- if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
- {
- free_arr(this.last_render_list);
- instances_to_draw = this.getRenderCellInstancesToDraw();
- this.render_list_stale = false;
- this.last_render_cells.copy(this.cur_render_cells);
- }
- else
- instances_to_draw = this.last_render_list;
- }
- else
- instances_to_draw = this.instances;
- var i, len, inst, last_inst = null;
- for (i = 0, len = instances_to_draw.length; i < len; ++i)
- {
- inst = instances_to_draw[i];
- if (inst === last_inst)
- continue;
- this.drawInstance(inst, layer_ctx);
- last_inst = inst;
- }
- if (this.useRenderCells)
- this.last_render_list = instances_to_draw;
- layer_ctx.restore();
- if (this.render_offscreen)
- {
- ctx.globalCompositeOperation = this.compositeOp;
- ctx.globalAlpha = this.opacity;
- ctx.drawImage(layer_canvas, 0, 0);
- }
- };
- Layer.prototype.drawInstance = function(inst, layer_ctx)
- {
- if (!inst.visible || inst.width === 0 || inst.height === 0)
- return;
- inst.update_bbox();
- var bbox = inst.bbox;
- if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
- return;
- layer_ctx.globalCompositeOperation = inst.compositeOp;
- inst.draw(layer_ctx);
- };
- Layer.prototype.updateViewport = function (ctx)
- {
- this.disableAngle = true;
- var px = this.canvasToLayer(0, 0, true, true);
- var py = this.canvasToLayer(0, 0, false, true);
- this.disableAngle = false;
- if (this.runtime.pixel_rounding)
- {
- px = Math.round(px);
- py = Math.round(py);
- }
- this.rotateViewport(px, py, ctx);
- };
- Layer.prototype.rotateViewport = function (px, py, ctx)
- {
- var myscale = this.getScale();
- this.viewLeft = px;
- this.viewTop = py;
- this.viewRight = px + (this.runtime.draw_width * (1 / myscale));
- this.viewBottom = py + (this.runtime.draw_height * (1 / myscale));
- var temp;
- if (this.viewLeft > this.viewRight)
- {
- temp = this.viewLeft;
- this.viewLeft = this.viewRight;
- this.viewRight = temp;
- }
- if (this.viewTop > this.viewBottom)
- {
- temp = this.viewTop;
- this.viewTop = this.viewBottom;
- this.viewBottom = temp;
- }
- var myAngle = this.getAngle();
- if (myAngle !== 0)
- {
- if (ctx)
- {
- ctx.translate(this.runtime.draw_width / 2, this.runtime.draw_height / 2);
- ctx.rotate(-myAngle);
- ctx.translate(this.runtime.draw_width / -2, this.runtime.draw_height / -2);
- }
- this.tmprect.set(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom);
- this.tmprect.offset((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
- this.tmpquad.set_from_rotated_rect(this.tmprect, myAngle);
- this.tmpquad.bounding_box(this.tmprect);
- this.tmprect.offset((this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2);
- this.viewLeft = this.tmprect.left;
- this.viewTop = this.tmprect.top;
- this.viewRight = this.tmprect.right;
- this.viewBottom = this.tmprect.bottom;
- }
- }
- Layer.prototype.drawGL_earlyZPass = function (glw)
- {
- var windowWidth = this.runtime.draw_width;
- var windowHeight = this.runtime.draw_height;
- var shaderindex = 0;
- var etindex = 0;
- this.render_offscreen = this.forceOwnTexture;
- if (this.render_offscreen)
- {
- if (!this.runtime.layer_tex)
- {
- this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
- {
- glw.deleteTexture(this.runtime.layer_tex);
- this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- glw.setRenderingToTexture(this.runtime.layer_tex);
- }
- this.disableAngle = true;
- var px = this.canvasToLayer(0, 0, true, true);
- var py = this.canvasToLayer(0, 0, false, true);
- this.disableAngle = false;
- if (this.runtime.pixel_rounding)
- {
- px = Math.round(px);
- py = Math.round(py);
- }
- this.rotateViewport(px, py, null);
- var myscale = this.getScale();
- glw.resetModelView();
- glw.scale(myscale, myscale);
- glw.rotateZ(-this.getAngle());
- glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
- glw.updateModelView();
- var instances_to_draw;
- if (this.useRenderCells)
- {
- this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
- this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
- this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
- this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
- if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
- {
- free_arr(this.last_render_list);
- instances_to_draw = this.getRenderCellInstancesToDraw();
- this.render_list_stale = false;
- this.last_render_cells.copy(this.cur_render_cells);
- }
- else
- instances_to_draw = this.last_render_list;
- }
- else
- instances_to_draw = this.instances;
- var i, inst, last_inst = null;
- for (i = instances_to_draw.length - 1; i >= 0; --i)
- {
- inst = instances_to_draw[i];
- if (inst === last_inst)
- continue;
- this.drawInstanceGL_earlyZPass(instances_to_draw[i], glw);
- last_inst = inst;
- }
- if (this.useRenderCells)
- this.last_render_list = instances_to_draw;
- if (!this.transparent)
- {
- this.clear_earlyz_index = this.runtime.earlyz_index++;
- glw.setEarlyZIndex(this.clear_earlyz_index);
- glw.setColorFillMode(1, 1, 1, 1);
- glw.fullscreenQuad(); // fill remaining space in depth buffer with current Z value
- glw.restoreEarlyZMode();
- }
- };
- Layer.prototype.drawGL = function (glw)
- {
- var windowWidth = this.runtime.draw_width;
- var windowHeight = this.runtime.draw_height;
- var shaderindex = 0;
- var etindex = 0;
- this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.active_effect_types.length > 0 || this.blend_mode !== 0);
- if (this.render_offscreen)
- {
- if (!this.runtime.layer_tex)
- {
- this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
- {
- glw.deleteTexture(this.runtime.layer_tex);
- this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
- }
- glw.setRenderingToTexture(this.runtime.layer_tex);
- if (this.transparent)
- glw.clear(0, 0, 0, 0);
- }
- if (!this.transparent)
- {
- if (this.runtime.enableFrontToBack)
- {
- glw.setEarlyZIndex(this.clear_earlyz_index);
- glw.setColorFillMode(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
- glw.fullscreenQuad();
- glw.setTextureFillMode();
- }
- else
- {
- glw.clear(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
- }
- }
- this.disableAngle = true;
- var px = this.canvasToLayer(0, 0, true, true);
- var py = this.canvasToLayer(0, 0, false, true);
- this.disableAngle = false;
- if (this.runtime.pixel_rounding)
- {
- px = Math.round(px);
- py = Math.round(py);
- }
- this.rotateViewport(px, py, null);
- var myscale = this.getScale();
- glw.resetModelView();
- glw.scale(myscale, myscale);
- glw.rotateZ(-this.getAngle());
- glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
- glw.updateModelView();
- var instances_to_draw;
- if (this.useRenderCells)
- {
- this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
- this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
- this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
- this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
- if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
- {
- free_arr(this.last_render_list);
- instances_to_draw = this.getRenderCellInstancesToDraw();
- this.render_list_stale = false;
- this.last_render_cells.copy(this.cur_render_cells);
- }
- else
- instances_to_draw = this.last_render_list;
- }
- else
- instances_to_draw = this.instances;
- var i, len, inst, last_inst = null;
- for (i = 0, len = instances_to_draw.length; i < len; ++i)
- {
- inst = instances_to_draw[i];
- if (inst === last_inst)
- continue;
- this.drawInstanceGL(instances_to_draw[i], glw);
- last_inst = inst;
- }
- if (this.useRenderCells)
- this.last_render_list = instances_to_draw;
- if (this.render_offscreen)
- {
- shaderindex = this.active_effect_types.length ? this.active_effect_types[0].shaderindex : 0;
- etindex = this.active_effect_types.length ? this.active_effect_types[0].index : 0;
- if (this.active_effect_types.length === 0 || (this.active_effect_types.length === 1 &&
- !glw.programUsesCrossSampling(shaderindex) && this.opacity === 1))
- {
- if (this.active_effect_types.length === 1)
- {
- glw.switchProgram(shaderindex);
- glw.setProgramParameters(this.layout.getRenderTarget(), // backTex
- 1.0 / this.runtime.draw_width, // pixelWidth
- 1.0 / this.runtime.draw_height, // pixelHeight
- 0.0, 0.0, // destStart
- 1.0, 1.0, // destEnd
- myscale, // layerScale
- this.getAngle(),
- this.viewLeft, this.viewTop,
- (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
- this.runtime.kahanTime.sum,
- this.effect_params[etindex]); // fx parameters
- if (glw.programIsAnimated(shaderindex))
- this.runtime.redraw = true;
- }
- else
- glw.switchProgram(0);
- glw.setRenderingToTexture(this.layout.getRenderTarget());
- glw.setOpacity(this.opacity);
- glw.setTexture(this.runtime.layer_tex);
- glw.setBlend(this.srcBlend, this.destBlend);
- glw.resetModelView();
- glw.updateModelView();
- var halfw = this.runtime.draw_width / 2;
- var halfh = this.runtime.draw_height / 2;
- glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
- glw.setTexture(null);
- }
- else
- {
- this.layout.renderEffectChain(glw, this, null, this.layout.getRenderTarget());
- }
- }
- };
- Layer.prototype.drawInstanceGL = function (inst, glw)
- {
-;
- if (!inst.visible || inst.width === 0 || inst.height === 0)
- return;
- inst.update_bbox();
- var bbox = inst.bbox;
- if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
- return;
- glw.setEarlyZIndex(inst.earlyz_index);
- if (inst.uses_shaders)
- {
- this.drawInstanceWithShadersGL(inst, glw);
- }
- else
- {
- glw.switchProgram(0); // un-set any previously set shader
- glw.setBlend(inst.srcBlend, inst.destBlend);
- inst.drawGL(glw);
- }
- };
- Layer.prototype.drawInstanceGL_earlyZPass = function (inst, glw)
- {
-;
- if (!inst.visible || inst.width === 0 || inst.height === 0)
- return;
- inst.update_bbox();
- var bbox = inst.bbox;
- if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
- return;
- inst.earlyz_index = this.runtime.earlyz_index++;
- if (inst.blend_mode !== 0 || inst.opacity !== 1 || !inst.shaders_preserve_opaqueness || !inst.drawGL_earlyZPass)
- return;
- glw.setEarlyZIndex(inst.earlyz_index);
- inst.drawGL_earlyZPass(glw);
- };
- Layer.prototype.drawInstanceWithShadersGL = function (inst, glw)
- {
- var shaderindex = inst.active_effect_types[0].shaderindex;
- var etindex = inst.active_effect_types[0].index;
- var myscale = this.getScale();
- if (inst.active_effect_types.length === 1 && !glw.programUsesCrossSampling(shaderindex) &&
- !glw.programExtendsBox(shaderindex) && ((!inst.angle && !inst.layer.getAngle()) || !glw.programUsesDest(shaderindex)) &&
- inst.opacity === 1 && !inst.type.plugin.must_predraw)
- {
- glw.switchProgram(shaderindex);
- glw.setBlend(inst.srcBlend, inst.destBlend);
- if (glw.programIsAnimated(shaderindex))
- this.runtime.redraw = true;
- var destStartX = 0, destStartY = 0, destEndX = 0, destEndY = 0;
- if (glw.programUsesDest(shaderindex))
- {
- var bbox = inst.bbox;
- var screenleft = this.layerToCanvas(bbox.left, bbox.top, true, true);
- var screentop = this.layerToCanvas(bbox.left, bbox.top, false, true);
- var screenright = this.layerToCanvas(bbox.right, bbox.bottom, true, true);
- var screenbottom = this.layerToCanvas(bbox.right, bbox.bottom, false, true);
- destStartX = screenleft / windowWidth;
- destStartY = 1 - screentop / windowHeight;
- destEndX = screenright / windowWidth;
- destEndY = 1 - screenbottom / windowHeight;
- }
- var pixelWidth;
- var pixelHeight;
- if (inst.curFrame && inst.curFrame.texture_img)
- {
- var img = inst.curFrame.texture_img;
- pixelWidth = 1.0 / img.width;
- pixelHeight = 1.0 / img.height;
- }
- else
- {
- pixelWidth = 1.0 / inst.width;
- pixelHeight = 1.0 / inst.height;
- }
- glw.setProgramParameters(this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget(), // backTex
- pixelWidth,
- pixelHeight,
- destStartX, destStartY,
- destEndX, destEndY,
- myscale,
- this.getAngle(),
- this.viewLeft, this.viewTop,
- (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
- this.runtime.kahanTime.sum,
- inst.effect_params[etindex]);
- inst.drawGL(glw);
- }
- else
- {
- this.layout.renderEffectChain(glw, this, inst, this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget());
- glw.resetModelView();
- glw.scale(myscale, myscale);
- glw.rotateZ(-this.getAngle());
- glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
- glw.updateModelView();
- }
- };
- Layer.prototype.canvasToLayer = function (ptx, pty, getx, using_draw_area)
- {
- var multiplier = this.runtime.devicePixelRatio;
- if (this.runtime.isRetina)
- {
- ptx *= multiplier;
- pty *= multiplier;
- }
- var ox = this.runtime.parallax_x_origin;
- var oy = this.runtime.parallax_y_origin;
- var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
- var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
- var x = par_x;
- var y = par_y;
- var invScale = 1 / this.getScale(!using_draw_area);
- if (using_draw_area)
- {
- x -= (this.runtime.draw_width * invScale) / 2;
- y -= (this.runtime.draw_height * invScale) / 2;
- }
- else
- {
- x -= (this.runtime.width * invScale) / 2;
- y -= (this.runtime.height * invScale) / 2;
- }
- x += ptx * invScale;
- y += pty * invScale;
- var a = this.getAngle();
- if (a !== 0)
- {
- x -= par_x;
- y -= par_y;
- var cosa = Math.cos(a);
- var sina = Math.sin(a);
- var x_temp = (x * cosa) - (y * sina);
- y = (y * cosa) + (x * sina);
- x = x_temp;
- x += par_x;
- y += par_y;
- }
- return getx ? x : y;
- };
- Layer.prototype.layerToCanvas = function (ptx, pty, getx, using_draw_area)
- {
- var ox = this.runtime.parallax_x_origin;
- var oy = this.runtime.parallax_y_origin;
- var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
- var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
- var x = par_x;
- var y = par_y;
- var a = this.getAngle();
- if (a !== 0)
- {
- ptx -= par_x;
- pty -= par_y;
- var cosa = Math.cos(-a);
- var sina = Math.sin(-a);
- var x_temp = (ptx * cosa) - (pty * sina);
- pty = (pty * cosa) + (ptx * sina);
- ptx = x_temp;
- ptx += par_x;
- pty += par_y;
- }
- var invScale = 1 / this.getScale(!using_draw_area);
- if (using_draw_area)
- {
- x -= (this.runtime.draw_width * invScale) / 2;
- y -= (this.runtime.draw_height * invScale) / 2;
- }
- else
- {
- x -= (this.runtime.width * invScale) / 2;
- y -= (this.runtime.height * invScale) / 2;
- }
- x = (ptx - x) / invScale;
- y = (pty - y) / invScale;
- var multiplier = this.runtime.devicePixelRatio;
- if (this.runtime.isRetina && !using_draw_area)
- {
- x /= multiplier;
- y /= multiplier;
- }
- return getx ? x : y;
- };
- Layer.prototype.rotatePt = function (x_, y_, getx)
- {
- if (this.getAngle() === 0)
- return getx ? x_ : y_;
- var nx = this.layerToCanvas(x_, y_, true);
- var ny = this.layerToCanvas(x_, y_, false);
- this.disableAngle = true;
- var px = this.canvasToLayer(nx, ny, true);
- var py = this.canvasToLayer(nx, ny, true);
- this.disableAngle = false;
- return getx ? px : py;
- };
- Layer.prototype.saveToJSON = function ()
- {
- var i, len, et;
- var o = {
- "s": this.scale,
- "a": this.angle,
- "vl": this.viewLeft,
- "vt": this.viewTop,
- "vr": this.viewRight,
- "vb": this.viewBottom,
- "v": this.visible,
- "bc": this.background_color,
- "t": this.transparent,
- "px": this.parallaxX,
- "py": this.parallaxY,
- "o": this.opacity,
- "zr": this.zoomRate,
- "fx": [],
- "cg": this.created_globals, // added r197; list of global UIDs already created
- "instances": []
- };
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- et = this.effect_types[i];
- o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
- }
- return o;
- };
- Layer.prototype.loadFromJSON = function (o)
- {
- var i, j, len, p, inst, fx;
- this.scale = o["s"];
- this.angle = o["a"];
- this.viewLeft = o["vl"];
- this.viewTop = o["vt"];
- this.viewRight = o["vr"];
- this.viewBottom = o["vb"];
- this.visible = o["v"];
- this.background_color = o["bc"];
- this.transparent = o["t"];
- this.parallaxX = o["px"];
- this.parallaxY = o["py"];
- this.opacity = o["o"];
- this.zoomRate = o["zr"];
- this.created_globals = o["cg"] || []; // added r197
- cr.shallowAssignArray(this.initial_instances, this.startup_initial_instances);
- var temp_set = new cr.ObjectSet();
- for (i = 0, len = this.created_globals.length; i < len; ++i)
- temp_set.add(this.created_globals[i]);
- for (i = 0, j = 0, len = this.initial_instances.length; i < len; ++i)
- {
- if (!temp_set.contains(this.initial_instances[i][2])) // UID in element 2
- {
- this.initial_instances[j] = this.initial_instances[i];
- ++j;
- }
- }
- cr.truncateArray(this.initial_instances, j);
- var ofx = o["fx"];
- for (i = 0, len = ofx.length; i < len; i++)
- {
- fx = this.getEffectByName(ofx[i]["name"]);
- if (!fx)
- continue; // must've gone missing
- fx.active = ofx[i]["active"];
- this.effect_params[fx.index] = ofx[i]["params"];
- }
- this.updateActiveEffects();
- this.instances.sort(sort_by_zindex);
- this.zindices_stale = true;
- };
- cr.layer = Layer;
-}());
-;
-(function()
-{
- var allUniqueSolModifiers = [];
- function testSolsMatch(arr1, arr2)
- {
- var i, len = arr1.length;
- switch (len) {
- case 0:
- return true;
- case 1:
- return arr1[0] === arr2[0];
- case 2:
- return arr1[0] === arr2[0] && arr1[1] === arr2[1];
- default:
- for (i = 0; i < len; i++)
- {
- if (arr1[i] !== arr2[i])
- return false;
- }
- return true;
- }
- };
- function solArraySorter(t1, t2)
- {
- return t1.index - t2.index;
- };
- function findMatchingSolModifier(arr)
- {
- var i, len, u, temp, subarr;
- if (arr.length === 2)
- {
- if (arr[0].index > arr[1].index)
- {
- temp = arr[0];
- arr[0] = arr[1];
- arr[1] = temp;
- }
- }
- else if (arr.length > 2)
- arr.sort(solArraySorter); // so testSolsMatch compares in same order
- if (arr.length >= allUniqueSolModifiers.length)
- allUniqueSolModifiers.length = arr.length + 1;
- if (!allUniqueSolModifiers[arr.length])
- allUniqueSolModifiers[arr.length] = [];
- subarr = allUniqueSolModifiers[arr.length];
- for (i = 0, len = subarr.length; i < len; i++)
- {
- u = subarr[i];
- if (testSolsMatch(arr, u))
- return u;
- }
- subarr.push(arr);
- return arr;
- };
- function EventSheet(runtime, m)
- {
- this.runtime = runtime;
- this.triggers = {};
- this.fasttriggers = {};
- this.hasRun = false;
- this.includes = new cr.ObjectSet(); // all event sheets included by this sheet, at first-level indirection only
- this.deep_includes = []; // all includes from this sheet recursively, in trigger order
- this.already_included_sheets = []; // used while building deep_includes
- this.name = m[0];
- var em = m[1]; // events model
- this.events = []; // triggers won't make it to this array
- var i, len;
- for (i = 0, len = em.length; i < len; i++)
- this.init_event(em[i], null, this.events);
- };
- EventSheet.prototype.toString = function ()
- {
- return this.name;
- };
- EventSheet.prototype.init_event = function (m, parent, nontriggers)
- {
- switch (m[0]) {
- case 0: // event block
- {
- var block = new cr.eventblock(this, parent, m);
- cr.seal(block);
- if (block.orblock)
- {
- nontriggers.push(block);
- var i, len;
- for (i = 0, len = block.conditions.length; i < len; i++)
- {
- if (block.conditions[i].trigger)
- this.init_trigger(block, i);
- }
- }
- else
- {
- if (block.is_trigger())
- this.init_trigger(block, 0);
- else
- nontriggers.push(block);
- }
- break;
- }
- case 1: // variable
- {
- var v = new cr.eventvariable(this, parent, m);
- cr.seal(v);
- nontriggers.push(v);
- break;
- }
- case 2: // include
- {
- var inc = new cr.eventinclude(this, parent, m);
- cr.seal(inc);
- nontriggers.push(inc);
- break;
- }
- default:
-;
- }
- };
- EventSheet.prototype.postInit = function ()
- {
- var i, len;
- for (i = 0, len = this.events.length; i < len; i++)
- {
- this.events[i].postInit(i < len - 1 && this.events[i + 1].is_else_block);
- }
- };
- EventSheet.prototype.updateDeepIncludes = function ()
- {
- cr.clearArray(this.deep_includes);
- cr.clearArray(this.already_included_sheets);
- this.addDeepIncludes(this);
- cr.clearArray(this.already_included_sheets);
- };
- EventSheet.prototype.addDeepIncludes = function (root_sheet)
- {
- var i, len, inc, sheet;
- var deep_includes = root_sheet.deep_includes;
- var already_included_sheets = root_sheet.already_included_sheets;
- var arr = this.includes.valuesRef();
- for (i = 0, len = arr.length; i < len; ++i)
- {
- inc = arr[i];
- sheet = inc.include_sheet;
- if (!inc.isActive() || root_sheet === sheet || already_included_sheets.indexOf(sheet) > -1)
- continue;
- already_included_sheets.push(sheet);
- sheet.addDeepIncludes(root_sheet);
- deep_includes.push(sheet);
- }
- };
- EventSheet.prototype.run = function (from_include)
- {
- if (!this.runtime.resuming_breakpoint)
- {
- this.hasRun = true;
- if (!from_include)
- this.runtime.isRunningEvents = true;
- }
- var i, len;
- for (i = 0, len = this.events.length; i < len; i++)
- {
- var ev = this.events[i];
- ev.run();
- this.runtime.clearSol(ev.solModifiers);
- if (this.runtime.hasPendingInstances)
- this.runtime.ClearDeathRow();
- }
- if (!from_include)
- this.runtime.isRunningEvents = false;
- };
- function isPerformanceSensitiveTrigger(method)
- {
- if (cr.plugins_.Sprite && method === cr.plugins_.Sprite.prototype.cnds.OnFrameChanged)
- {
- return true;
- }
- return false;
- };
- EventSheet.prototype.init_trigger = function (trig, index)
- {
- if (!trig.orblock)
- this.runtime.triggers_to_postinit.push(trig); // needs to be postInit'd later
- var i, len;
- var cnd = trig.conditions[index];
- var type_name;
- if (cnd.type)
- type_name = cnd.type.name;
- else
- type_name = "system";
- var fasttrigger = cnd.fasttrigger;
- var triggers = (fasttrigger ? this.fasttriggers : this.triggers);
- if (!triggers[type_name])
- triggers[type_name] = [];
- var obj_entry = triggers[type_name];
- var method = cnd.func;
- if (fasttrigger)
- {
- if (!cnd.parameters.length) // no parameters
- return;
- var firstparam = cnd.parameters[0];
- if (firstparam.type !== 1 || // not a string param
- firstparam.expression.type !== 2) // not a string literal node
- {
- return;
- }
- var fastevs;
- var firstvalue = firstparam.expression.value.toLowerCase();
- var i, len;
- for (i = 0, len = obj_entry.length; i < len; i++)
- {
- if (obj_entry[i].method == method)
- {
- fastevs = obj_entry[i].evs;
- if (!fastevs[firstvalue])
- fastevs[firstvalue] = [[trig, index]];
- else
- fastevs[firstvalue].push([trig, index]);
- return;
- }
- }
- fastevs = {};
- fastevs[firstvalue] = [[trig, index]];
- obj_entry.push({ method: method, evs: fastevs });
- }
- else
- {
- for (i = 0, len = obj_entry.length; i < len; i++)
- {
- if (obj_entry[i].method == method)
- {
- obj_entry[i].evs.push([trig, index]);
- return;
- }
- }
- if (isPerformanceSensitiveTrigger(method))
- obj_entry.unshift({ method: method, evs: [[trig, index]]});
- else
- obj_entry.push({ method: method, evs: [[trig, index]]});
- }
- };
- cr.eventsheet = EventSheet;
- function Selection(type)
- {
- this.type = type;
- this.instances = []; // subset of picked instances
- this.else_instances = []; // subset of unpicked instances
- this.select_all = true;
- };
- Selection.prototype.hasObjects = function ()
- {
- if (this.select_all)
- return this.type.instances.length;
- else
- return this.instances.length;
- };
- Selection.prototype.getObjects = function ()
- {
- if (this.select_all)
- return this.type.instances;
- else
- return this.instances;
- };
- /*
- Selection.prototype.ensure_picked = function (inst, skip_siblings)
- {
- var i, len;
- var orblock = inst.runtime.getCurrentEventStack().current_event.orblock;
- if (this.select_all)
- {
- this.select_all = false;
- if (orblock)
- {
- cr.shallowAssignArray(this.else_instances, inst.type.instances);
- cr.arrayFindRemove(this.else_instances, inst);
- }
- this.instances.length = 1;
- this.instances[0] = inst;
- }
- else
- {
- if (orblock)
- {
- i = this.else_instances.indexOf(inst);
- if (i !== -1)
- {
- this.instances.push(this.else_instances[i]);
- this.else_instances.splice(i, 1);
- }
- }
- else
- {
- if (this.instances.indexOf(inst) === -1)
- this.instances.push(inst);
- }
- }
- if (!skip_siblings)
- {
- }
- };
- */
- Selection.prototype.pick_one = function (inst)
- {
- if (!inst)
- return;
- if (inst.runtime.getCurrentEventStack().current_event.orblock)
- {
- if (this.select_all)
- {
- cr.clearArray(this.instances);
- cr.shallowAssignArray(this.else_instances, inst.type.instances);
- this.select_all = false;
- }
- var i = this.else_instances.indexOf(inst);
- if (i !== -1)
- {
- this.instances.push(this.else_instances[i]);
- this.else_instances.splice(i, 1);
- }
- }
- else
- {
- this.select_all = false;
- cr.clearArray(this.instances);
- this.instances[0] = inst;
- }
- };
- cr.selection = Selection;
- function EventBlock(sheet, parent, m)
- {
- this.sheet = sheet;
- this.parent = parent;
- this.runtime = sheet.runtime;
- this.solModifiers = [];
- this.solModifiersIncludingParents = [];
- this.solWriterAfterCnds = false; // block does not change SOL after running its conditions
- this.group = false; // is group of events
- this.initially_activated = false; // if a group, is active on startup
- this.toplevelevent = false; // is an event block parented only by a top-level group
- this.toplevelgroup = false; // is parented only by other groups or is top-level (i.e. not in a subevent)
- this.has_else_block = false; // is followed by else
-;
- this.conditions = [];
- this.actions = [];
- this.subevents = [];
- this.group_name = "";
- this.group = false;
- this.initially_activated = false;
- this.group_active = false;
- this.contained_includes = null;
- if (m[1])
- {
- this.group_name = m[1][1].toLowerCase();
- this.group = true;
- this.initially_activated = !!m[1][0];
- this.contained_includes = [];
- this.group_active = this.initially_activated;
- this.runtime.allGroups.push(this);
- this.runtime.groups_by_name[this.group_name] = this;
- }
- this.orblock = m[2];
- this.sid = m[4];
- if (!this.group)
- this.runtime.blocksBySid[this.sid.toString()] = this;
- var i, len;
- var cm = m[5];
- for (i = 0, len = cm.length; i < len; i++)
- {
- var cnd = new cr.condition(this, cm[i]);
- cnd.index = i;
- cr.seal(cnd);
- this.conditions.push(cnd);
- /*
- if (cnd.is_logical())
- this.is_logical = true;
- if (cnd.type && !cnd.type.plugin.singleglobal && this.cndReferences.indexOf(cnd.type) === -1)
- this.cndReferences.push(cnd.type);
- */
- this.addSolModifier(cnd.type);
- }
- var am = m[6];
- for (i = 0, len = am.length; i < len; i++)
- {
- var act = new cr.action(this, am[i]);
- act.index = i;
- cr.seal(act);
- this.actions.push(act);
- }
- if (m.length === 8)
- {
- var em = m[7];
- for (i = 0, len = em.length; i < len; i++)
- this.sheet.init_event(em[i], this, this.subevents);
- }
- this.is_else_block = false;
- if (this.conditions.length)
- {
- this.is_else_block = (this.conditions[0].type == null && this.conditions[0].func == cr.system_object.prototype.cnds.Else);
- }
- };
- window["_c2hh_"] = "0764F5122709682D4499715308638A3CE8A82A1F";
- EventBlock.prototype.postInit = function (hasElse/*, prevBlock_*/)
- {
- var i, len;
- var p = this.parent;
- if (this.group)
- {
- this.toplevelgroup = true;
- while (p)
- {
- if (!p.group)
- {
- this.toplevelgroup = false;
- break;
- }
- p = p.parent;
- }
- }
- this.toplevelevent = !this.is_trigger() && (!this.parent || (this.parent.group && this.parent.toplevelgroup));
- this.has_else_block = !!hasElse;
- this.solModifiersIncludingParents = this.solModifiers.slice(0);
- p = this.parent;
- while (p)
- {
- for (i = 0, len = p.solModifiers.length; i < len; i++)
- this.addParentSolModifier(p.solModifiers[i]);
- p = p.parent;
- }
- this.solModifiers = findMatchingSolModifier(this.solModifiers);
- this.solModifiersIncludingParents = findMatchingSolModifier(this.solModifiersIncludingParents);
- var i, len/*, s*/;
- for (i = 0, len = this.conditions.length; i < len; i++)
- this.conditions[i].postInit();
- for (i = 0, len = this.actions.length; i < len; i++)
- this.actions[i].postInit();
- for (i = 0, len = this.subevents.length; i < len; i++)
- {
- this.subevents[i].postInit(i < len - 1 && this.subevents[i + 1].is_else_block);
- }
- /*
- if (this.is_else_block && this.prev_block)
- {
- for (i = 0, len = this.prev_block.solModifiers.length; i < len; i++)
- {
- s = this.prev_block.solModifiers[i];
- if (this.solModifiers.indexOf(s) === -1)
- this.solModifiers.push(s);
- }
- }
- */
- };
- EventBlock.prototype.setGroupActive = function (a)
- {
- if (this.group_active === !!a)
- return; // same state
- this.group_active = !!a;
- var i, len;
- for (i = 0, len = this.contained_includes.length; i < len; ++i)
- {
- this.contained_includes[i].updateActive();
- }
- if (len > 0 && this.runtime.running_layout.event_sheet)
- this.runtime.running_layout.event_sheet.updateDeepIncludes();
- };
- function addSolModifierToList(type, arr)
- {
- var i, len, t;
- if (!type)
- return;
- if (arr.indexOf(type) === -1)
- arr.push(type);
- if (type.is_contained)
- {
- for (i = 0, len = type.container.length; i < len; i++)
- {
- t = type.container[i];
- if (type === t)
- continue; // already handled
- if (arr.indexOf(t) === -1)
- arr.push(t);
- }
- }
- };
- EventBlock.prototype.addSolModifier = function (type)
- {
- addSolModifierToList(type, this.solModifiers);
- };
- EventBlock.prototype.addParentSolModifier = function (type)
- {
- addSolModifierToList(type, this.solModifiersIncludingParents);
- };
- EventBlock.prototype.setSolWriterAfterCnds = function ()
- {
- this.solWriterAfterCnds = true;
- if (this.parent)
- this.parent.setSolWriterAfterCnds();
- };
- EventBlock.prototype.is_trigger = function ()
- {
- if (!this.conditions.length) // no conditions
- return false;
- else
- return this.conditions[0].trigger;
- };
- EventBlock.prototype.run = function ()
- {
- var i, len, c, any_true = false, cnd_result;
- var runtime = this.runtime;
- var evinfo = this.runtime.getCurrentEventStack();
- evinfo.current_event = this;
- var conditions = this.conditions;
- if (!this.is_else_block)
- evinfo.else_branch_ran = false;
- if (this.orblock)
- {
- if (conditions.length === 0)
- any_true = true; // be sure to run if empty block
- evinfo.cndindex = 0
- for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
- {
- c = conditions[evinfo.cndindex];
- if (c.trigger) // skip triggers when running OR block
- continue;
- cnd_result = c.run();
- if (cnd_result) // make sure all conditions run and run if any were true
- any_true = true;
- }
- evinfo.last_event_true = any_true;
- if (any_true)
- this.run_actions_and_subevents();
- }
- else
- {
- evinfo.cndindex = 0
- for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
- {
- cnd_result = conditions[evinfo.cndindex].run();
- if (!cnd_result) // condition failed
- {
- evinfo.last_event_true = false;
- if (this.toplevelevent && runtime.hasPendingInstances)
- runtime.ClearDeathRow();
- return; // bail out now
- }
- }
- evinfo.last_event_true = true;
- this.run_actions_and_subevents();
- }
- this.end_run(evinfo);
- };
- EventBlock.prototype.end_run = function (evinfo)
- {
- if (evinfo.last_event_true && this.has_else_block)
- evinfo.else_branch_ran = true;
- if (this.toplevelevent && this.runtime.hasPendingInstances)
- this.runtime.ClearDeathRow();
- };
- EventBlock.prototype.run_orblocktrigger = function (index)
- {
- var evinfo = this.runtime.getCurrentEventStack();
- evinfo.current_event = this;
- if (this.conditions[index].run())
- {
- this.run_actions_and_subevents();
- this.runtime.getCurrentEventStack().last_event_true = true;
- }
- };
- EventBlock.prototype.run_actions_and_subevents = function ()
- {
- var evinfo = this.runtime.getCurrentEventStack();
- var len;
- for (evinfo.actindex = 0, len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
- {
- if (this.actions[evinfo.actindex].run())
- return;
- }
- this.run_subevents();
- };
- EventBlock.prototype.resume_actions_and_subevents = function ()
- {
- var evinfo = this.runtime.getCurrentEventStack();
- var len;
- for (len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
- {
- if (this.actions[evinfo.actindex].run())
- return;
- }
- this.run_subevents();
- };
- EventBlock.prototype.run_subevents = function ()
- {
- if (!this.subevents.length)
- return;
- var i, len, subev, pushpop/*, skipped_pop = false, pop_modifiers = null*/;
- var last = this.subevents.length - 1;
- this.runtime.pushEventStack(this);
- if (this.solWriterAfterCnds)
- {
- for (i = 0, len = this.subevents.length; i < len; i++)
- {
- subev = this.subevents[i];
- pushpop = (!this.toplevelgroup || (!this.group && i < last));
- if (pushpop)
- this.runtime.pushCopySol(subev.solModifiers);
- subev.run();
- if (pushpop)
- this.runtime.popSol(subev.solModifiers);
- else
- this.runtime.clearSol(subev.solModifiers);
- }
- }
- else
- {
- for (i = 0, len = this.subevents.length; i < len; i++)
- {
- this.subevents[i].run();
- }
- }
- this.runtime.popEventStack();
- };
- EventBlock.prototype.run_pretrigger = function ()
- {
- var evinfo = this.runtime.getCurrentEventStack();
- evinfo.current_event = this;
- var any_true = false;
- var i, len;
- for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
- {
-;
- if (this.conditions[evinfo.cndindex].run())
- any_true = true;
- else if (!this.orblock) // condition failed (let OR blocks run all conditions anyway)
- return false; // bail out
- }
- return this.orblock ? any_true : true;
- };
- EventBlock.prototype.retrigger = function ()
- {
- this.runtime.execcount++;
- var prevcndindex = this.runtime.getCurrentEventStack().cndindex;
- var len;
- var evinfo = this.runtime.pushEventStack(this);
- if (!this.orblock)
- {
- for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
- {
- if (!this.conditions[evinfo.cndindex].run()) // condition failed
- {
- this.runtime.popEventStack(); // moving up level of recursion
- return false; // bail out
- }
- }
- }
- this.run_actions_and_subevents();
- this.runtime.popEventStack();
- return true; // ran an iteration
- };
- EventBlock.prototype.isFirstConditionOfType = function (cnd)
- {
- var cndindex = cnd.index;
- if (cndindex === 0)
- return true;
- --cndindex;
- for ( ; cndindex >= 0; --cndindex)
- {
- if (this.conditions[cndindex].type === cnd.type)
- return false;
- }
- return true;
- };
- cr.eventblock = EventBlock;
- function Condition(block, m)
- {
- this.block = block;
- this.sheet = block.sheet;
- this.runtime = block.runtime;
- this.parameters = [];
- this.results = [];
- this.extra = {}; // for plugins to stow away some custom info
- this.index = -1;
- this.anyParamVariesPerInstance = false;
- this.func = this.runtime.GetObjectReference(m[1]);
-;
- this.trigger = (m[3] > 0);
- this.fasttrigger = (m[3] === 2);
- this.looping = m[4];
- this.inverted = m[5];
- this.isstatic = m[6];
- this.sid = m[7];
- this.runtime.cndsBySid[this.sid.toString()] = this;
- if (m[0] === -1) // system object
- {
- this.type = null;
- this.run = this.run_system;
- this.behaviortype = null;
- this.beh_index = -1;
- }
- else
- {
- this.type = this.runtime.types_by_index[m[0]];
-;
- if (this.isstatic)
- this.run = this.run_static;
- else
- this.run = this.run_object;
- if (m[2])
- {
- this.behaviortype = this.type.getBehaviorByName(m[2]);
-;
- this.beh_index = this.type.getBehaviorIndexByName(m[2]);
-;
- }
- else
- {
- this.behaviortype = null;
- this.beh_index = -1;
- }
- if (this.block.parent)
- this.block.parent.setSolWriterAfterCnds();
- }
- if (this.fasttrigger)
- this.run = this.run_true;
- if (m.length === 10)
- {
- var i, len;
- var em = m[9];
- for (i = 0, len = em.length; i < len; i++)
- {
- var param = new cr.parameter(this, em[i]);
- cr.seal(param);
- this.parameters.push(param);
- }
- this.results.length = em.length;
- }
- };
- Condition.prototype.postInit = function ()
- {
- var i, len, p;
- for (i = 0, len = this.parameters.length; i < len; i++)
- {
- p = this.parameters[i];
- p.postInit();
- if (p.variesPerInstance)
- this.anyParamVariesPerInstance = true;
- }
- };
- /*
- Condition.prototype.is_logical = function ()
- {
- return !this.type || this.type.plugin.singleglobal;
- };
- */
- Condition.prototype.run_true = function ()
- {
- return true;
- };
- Condition.prototype.run_system = function ()
- {
- var i, len;
- for (i = 0, len = this.parameters.length; i < len; i++)
- this.results[i] = this.parameters[i].get();
- return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted);
- };
- Condition.prototype.run_static = function ()
- {
- var i, len;
- for (i = 0, len = this.parameters.length; i < len; i++)
- this.results[i] = this.parameters[i].get();
- var ret = this.func.apply(this.behaviortype ? this.behaviortype : this.type, this.results);
- this.type.applySolToContainer();
- return ret;
- };
- Condition.prototype.run_object = function ()
- {
- var i, j, k, leni, lenj, p, ret, met, inst, s, sol2;
- var type = this.type;
- var sol = type.getCurrentSol();
- var is_orblock = this.block.orblock && !this.trigger; // triggers in OR blocks need to work normally
- var offset = 0;
- var is_contained = type.is_contained;
- var is_family = type.is_family;
- var family_index = type.family_index;
- var beh_index = this.beh_index;
- var is_beh = (beh_index > -1);
- var params_vary = this.anyParamVariesPerInstance;
- var parameters = this.parameters;
- var results = this.results;
- var inverted = this.inverted;
- var func = this.func;
- var arr, container;
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- {
- p = parameters[j];
- if (!p.variesPerInstance)
- results[j] = p.get(0);
- }
- }
- else
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- results[j] = parameters[j].get(0);
- }
- if (sol.select_all) {
- cr.clearArray(sol.instances); // clear contents
- cr.clearArray(sol.else_instances);
- arr = type.instances;
- for (i = 0, leni = arr.length; i < leni; ++i)
- {
- inst = arr[i];
-;
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- {
- p = parameters[j];
- if (p.variesPerInstance)
- results[j] = p.get(i); // default SOL index is current object
- }
- }
- if (is_beh)
- {
- offset = 0;
- if (is_family)
- {
- offset = inst.type.family_beh_map[family_index];
- }
- ret = func.apply(inst.behavior_insts[beh_index + offset], results);
- }
- else
- ret = func.apply(inst, results);
- met = cr.xor(ret, inverted);
- if (met)
- sol.instances.push(inst);
- else if (is_orblock) // in OR blocks, keep the instances not meeting the condition for subsequent testing
- sol.else_instances.push(inst);
- }
- if (type.finish)
- type.finish(true);
- sol.select_all = false;
- type.applySolToContainer();
- return sol.hasObjects();
- }
- else {
- k = 0;
- var using_else_instances = (is_orblock && !this.block.isFirstConditionOfType(this));
- arr = (using_else_instances ? sol.else_instances : sol.instances);
- var any_true = false;
- for (i = 0, leni = arr.length; i < leni; ++i)
- {
- inst = arr[i];
-;
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- {
- p = parameters[j];
- if (p.variesPerInstance)
- results[j] = p.get(i); // default SOL index is current object
- }
- }
- if (is_beh)
- {
- offset = 0;
- if (is_family)
- {
- offset = inst.type.family_beh_map[family_index];
- }
- ret = func.apply(inst.behavior_insts[beh_index + offset], results);
- }
- else
- ret = func.apply(inst, results);
- if (cr.xor(ret, inverted))
- {
- any_true = true;
- if (using_else_instances)
- {
- sol.instances.push(inst);
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- s.type.getCurrentSol().instances.push(s);
- }
- }
- }
- else
- {
- arr[k] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- s.type.getCurrentSol().instances[k] = s;
- }
- }
- k++;
- }
- }
- else
- {
- if (using_else_instances)
- {
- arr[k] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- s.type.getCurrentSol().else_instances[k] = s;
- }
- }
- k++;
- }
- else if (is_orblock)
- {
- sol.else_instances.push(inst);
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- s.type.getCurrentSol().else_instances.push(s);
- }
- }
- }
- }
- }
- cr.truncateArray(arr, k);
- if (is_contained)
- {
- container = type.container;
- for (i = 0, leni = container.length; i < leni; i++)
- {
- sol2 = container[i].getCurrentSol();
- if (using_else_instances)
- cr.truncateArray(sol2.else_instances, k);
- else
- cr.truncateArray(sol2.instances, k);
- }
- }
- var pick_in_finish = any_true; // don't pick in finish() if we're only doing the logic test below
- if (using_else_instances && !any_true)
- {
- for (i = 0, leni = sol.instances.length; i < leni; i++)
- {
- inst = sol.instances[i];
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; j++)
- {
- p = parameters[j];
- if (p.variesPerInstance)
- results[j] = p.get(i);
- }
- }
- if (is_beh)
- ret = func.apply(inst.behavior_insts[beh_index], results);
- else
- ret = func.apply(inst, results);
- if (cr.xor(ret, inverted))
- {
- any_true = true;
- break; // got our flag, don't need to test any more
- }
- }
- }
- if (type.finish)
- type.finish(pick_in_finish || is_orblock);
- return is_orblock ? any_true : sol.hasObjects();
- }
- };
- cr.condition = Condition;
- function Action(block, m)
- {
- this.block = block;
- this.sheet = block.sheet;
- this.runtime = block.runtime;
- this.parameters = [];
- this.results = [];
- this.extra = {}; // for plugins to stow away some custom info
- this.index = -1;
- this.anyParamVariesPerInstance = false;
- this.func = this.runtime.GetObjectReference(m[1]);
-;
- if (m[0] === -1) // system
- {
- this.type = null;
- this.run = this.run_system;
- this.behaviortype = null;
- this.beh_index = -1;
- }
- else
- {
- this.type = this.runtime.types_by_index[m[0]];
-;
- this.run = this.run_object;
- if (m[2])
- {
- this.behaviortype = this.type.getBehaviorByName(m[2]);
-;
- this.beh_index = this.type.getBehaviorIndexByName(m[2]);
-;
- }
- else
- {
- this.behaviortype = null;
- this.beh_index = -1;
- }
- }
- this.sid = m[3];
- this.runtime.actsBySid[this.sid.toString()] = this;
- if (m.length === 6)
- {
- var i, len;
- var em = m[5];
- for (i = 0, len = em.length; i < len; i++)
- {
- var param = new cr.parameter(this, em[i]);
- cr.seal(param);
- this.parameters.push(param);
- }
- this.results.length = em.length;
- }
- };
- Action.prototype.postInit = function ()
- {
- var i, len, p;
- for (i = 0, len = this.parameters.length; i < len; i++)
- {
- p = this.parameters[i];
- p.postInit();
- if (p.variesPerInstance)
- this.anyParamVariesPerInstance = true;
- }
- };
- Action.prototype.run_system = function ()
- {
- var runtime = this.runtime;
- var i, len;
- var parameters = this.parameters;
- var results = this.results;
- for (i = 0, len = parameters.length; i < len; ++i)
- results[i] = parameters[i].get();
- return this.func.apply(runtime.system, results);
- };
- Action.prototype.run_object = function ()
- {
- var type = this.type;
- var beh_index = this.beh_index;
- var family_index = type.family_index;
- var params_vary = this.anyParamVariesPerInstance;
- var parameters = this.parameters;
- var results = this.results;
- var func = this.func;
- var instances = type.getCurrentSol().getObjects();
- var is_family = type.is_family;
- var is_beh = (beh_index > -1);
- var i, j, leni, lenj, p, inst, offset;
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- {
- p = parameters[j];
- if (!p.variesPerInstance)
- results[j] = p.get(0);
- }
- }
- else
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- results[j] = parameters[j].get(0);
- }
- for (i = 0, leni = instances.length; i < leni; ++i)
- {
- inst = instances[i];
- if (params_vary)
- {
- for (j = 0, lenj = parameters.length; j < lenj; ++j)
- {
- p = parameters[j];
- if (p.variesPerInstance)
- results[j] = p.get(i); // pass i to use as default SOL index
- }
- }
- if (is_beh)
- {
- offset = 0;
- if (is_family)
- {
- offset = inst.type.family_beh_map[family_index];
- }
- func.apply(inst.behavior_insts[beh_index + offset], results);
- }
- else
- func.apply(inst, results);
- }
- return false;
- };
- cr.action = Action;
- var tempValues = [];
- var tempValuesPtr = -1;
- function pushTempValue()
- {
- tempValuesPtr++;
- if (tempValues.length === tempValuesPtr)
- tempValues.push(new cr.expvalue());
- return tempValues[tempValuesPtr];
- };
- function popTempValue()
- {
- tempValuesPtr--;
- };
- function Parameter(owner, m)
- {
- this.owner = owner;
- this.block = owner.block;
- this.sheet = owner.sheet;
- this.runtime = owner.runtime;
- this.type = m[0];
- this.expression = null;
- this.solindex = 0;
- this.get = null;
- this.combosel = 0;
- this.layout = null;
- this.key = 0;
- this.object = null;
- this.index = 0;
- this.varname = null;
- this.eventvar = null;
- this.fileinfo = null;
- this.subparams = null;
- this.variadicret = null;
- this.subparams = null;
- this.variadicret = null;
- this.variesPerInstance = false;
- var i, len, param;
- switch (m[0])
- {
- case 0: // number
- case 7: // any
- this.expression = new cr.expNode(this, m[1]);
- this.solindex = 0;
- this.get = this.get_exp;
- break;
- case 1: // string
- this.expression = new cr.expNode(this, m[1]);
- this.solindex = 0;
- this.get = this.get_exp_str;
- break;
- case 5: // layer
- this.expression = new cr.expNode(this, m[1]);
- this.solindex = 0;
- this.get = this.get_layer;
- break;
- case 3: // combo
- case 8: // cmp
- this.combosel = m[1];
- this.get = this.get_combosel;
- break;
- case 6: // layout
- this.layout = this.runtime.layouts[m[1]];
-;
- this.get = this.get_layout;
- break;
- case 9: // keyb
- this.key = m[1];
- this.get = this.get_key;
- break;
- case 4: // object
- this.object = this.runtime.types_by_index[m[1]];
-;
- this.get = this.get_object;
- this.block.addSolModifier(this.object);
- if (this.owner instanceof cr.action)
- this.block.setSolWriterAfterCnds();
- else if (this.block.parent)
- this.block.parent.setSolWriterAfterCnds();
- break;
- case 10: // instvar
- this.index = m[1];
- if (owner.type && owner.type.is_family)
- {
- this.get = this.get_familyvar;
- this.variesPerInstance = true;
- }
- else
- this.get = this.get_instvar;
- break;
- case 11: // eventvar
- this.varname = m[1];
- this.eventvar = null;
- this.get = this.get_eventvar;
- break;
- case 2: // audiofile ["name", ismusic]
- case 12: // fileinfo "name"
- this.fileinfo = m[1];
- this.get = this.get_audiofile;
- break;
- case 13: // variadic
- this.get = this.get_variadic;
- this.subparams = [];
- this.variadicret = [];
- for (i = 1, len = m.length; i < len; i++)
- {
- param = new cr.parameter(this.owner, m[i]);
- cr.seal(param);
- this.subparams.push(param);
- this.variadicret.push(0);
- }
- break;
- default:
-;
- }
- };
- Parameter.prototype.postInit = function ()
- {
- var i, len;
- if (this.type === 11) // eventvar
- {
- this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent);
-;
- }
- else if (this.type === 13) // variadic, postInit all sub-params
- {
- for (i = 0, len = this.subparams.length; i < len; i++)
- this.subparams[i].postInit();
- }
- if (this.expression)
- this.expression.postInit();
- };
- Parameter.prototype.maybeVaryForType = function (t)
- {
- if (this.variesPerInstance)
- return; // already varies per instance, no need to check again
- if (!t)
- return; // never vary for system type
- if (!t.plugin.singleglobal)
- {
- this.variesPerInstance = true;
- return;
- }
- };
- Parameter.prototype.setVaries = function ()
- {
- this.variesPerInstance = true;
- };
- Parameter.prototype.get_exp = function (solindex)
- {
- this.solindex = solindex || 0; // default SOL index to use
- var temp = pushTempValue();
- this.expression.get(temp);
- popTempValue();
- return temp.data; // return actual JS value, not expvalue
- };
- Parameter.prototype.get_exp_str = function (solindex)
- {
- this.solindex = solindex || 0; // default SOL index to use
- var temp = pushTempValue();
- this.expression.get(temp);
- popTempValue();
- if (cr.is_string(temp.data))
- return temp.data;
- else
- return "";
- };
- Parameter.prototype.get_object = function ()
- {
- return this.object;
- };
- Parameter.prototype.get_combosel = function ()
- {
- return this.combosel;
- };
- Parameter.prototype.get_layer = function (solindex)
- {
- this.solindex = solindex || 0; // default SOL index to use
- var temp = pushTempValue();
- this.expression.get(temp);
- popTempValue();
- if (temp.is_number())
- return this.runtime.getLayerByNumber(temp.data);
- else
- return this.runtime.getLayerByName(temp.data);
- }
- Parameter.prototype.get_layout = function ()
- {
- return this.layout;
- };
- Parameter.prototype.get_key = function ()
- {
- return this.key;
- };
- Parameter.prototype.get_instvar = function ()
- {
- return this.index;
- };
- Parameter.prototype.get_familyvar = function (solindex_)
- {
- var solindex = solindex_ || 0;
- var familytype = this.owner.type;
- var realtype = null;
- var sol = familytype.getCurrentSol();
- var objs = sol.getObjects();
- if (objs.length)
- realtype = objs[solindex % objs.length].type;
- else if (sol.else_instances.length)
- realtype = sol.else_instances[solindex % sol.else_instances.length].type;
- else if (familytype.instances.length)
- realtype = familytype.instances[solindex % familytype.instances.length].type;
- else
- return 0;
- return this.index + realtype.family_var_map[familytype.family_index];
- };
- Parameter.prototype.get_eventvar = function ()
- {
- return this.eventvar;
- };
- Parameter.prototype.get_audiofile = function ()
- {
- return this.fileinfo;
- };
- Parameter.prototype.get_variadic = function ()
- {
- var i, len;
- for (i = 0, len = this.subparams.length; i < len; i++)
- {
- this.variadicret[i] = this.subparams[i].get();
- }
- return this.variadicret;
- };
- cr.parameter = Parameter;
- function EventVariable(sheet, parent, m)
- {
- this.sheet = sheet;
- this.parent = parent;
- this.runtime = sheet.runtime;
- this.solModifiers = [];
- this.name = m[1];
- this.vartype = m[2];
- this.initial = m[3];
- this.is_static = !!m[4];
- this.is_constant = !!m[5];
- this.sid = m[6];
- this.runtime.varsBySid[this.sid.toString()] = this;
- this.data = this.initial; // note: also stored in event stack frame for local nonstatic nonconst vars
- if (this.parent) // local var
- {
- if (this.is_static || this.is_constant)
- this.localIndex = -1;
- else
- this.localIndex = this.runtime.stackLocalCount++;
- this.runtime.all_local_vars.push(this);
- }
- else // global var
- {
- this.localIndex = -1;
- this.runtime.all_global_vars.push(this);
- }
- };
- EventVariable.prototype.postInit = function ()
- {
- this.solModifiers = findMatchingSolModifier(this.solModifiers);
- };
- EventVariable.prototype.setValue = function (x)
- {
-;
- var lvs = this.runtime.getCurrentLocalVarStack();
- if (!this.parent || this.is_static || !lvs)
- this.data = x;
- else // local nonstatic variable: use event stack to keep value at this level of recursion
- {
- if (this.localIndex >= lvs.length)
- lvs.length = this.localIndex + 1;
- lvs[this.localIndex] = x;
- }
- };
- EventVariable.prototype.getValue = function ()
- {
- var lvs = this.runtime.getCurrentLocalVarStack();
- if (!this.parent || this.is_static || !lvs || this.is_constant)
- return this.data;
- else // local nonstatic variable
- {
- if (this.localIndex >= lvs.length)
- {
- return this.initial;
- }
- if (typeof lvs[this.localIndex] === "undefined")
- {
- return this.initial;
- }
- return lvs[this.localIndex];
- }
- };
- EventVariable.prototype.run = function ()
- {
- if (this.parent && !this.is_static && !this.is_constant)
- this.setValue(this.initial);
- };
- cr.eventvariable = EventVariable;
- function EventInclude(sheet, parent, m)
- {
- this.sheet = sheet;
- this.parent = parent;
- this.runtime = sheet.runtime;
- this.solModifiers = [];
- this.include_sheet = null; // determined in postInit
- this.include_sheet_name = m[1];
- this.active = true;
- };
- EventInclude.prototype.toString = function ()
- {
- return "include:" + this.include_sheet.toString();
- };
- EventInclude.prototype.postInit = function ()
- {
- this.include_sheet = this.runtime.eventsheets[this.include_sheet_name];
-;
-;
- this.sheet.includes.add(this);
- this.solModifiers = findMatchingSolModifier(this.solModifiers);
- var p = this.parent;
- while (p)
- {
- if (p.group)
- p.contained_includes.push(this);
- p = p.parent;
- }
- this.updateActive();
- };
- EventInclude.prototype.run = function ()
- {
- if (this.parent)
- this.runtime.pushCleanSol(this.runtime.types_by_index);
- if (!this.include_sheet.hasRun)
- this.include_sheet.run(true); // from include
- if (this.parent)
- this.runtime.popSol(this.runtime.types_by_index);
- };
- EventInclude.prototype.updateActive = function ()
- {
- var p = this.parent;
- while (p)
- {
- if (p.group && !p.group_active)
- {
- this.active = false;
- return;
- }
- p = p.parent;
- }
- this.active = true;
- };
- EventInclude.prototype.isActive = function ()
- {
- return this.active;
- };
- cr.eventinclude = EventInclude;
- function EventStackFrame()
- {
- this.temp_parents_arr = [];
- this.reset(null);
- cr.seal(this);
- };
- EventStackFrame.prototype.reset = function (cur_event)
- {
- this.current_event = cur_event;
- this.cndindex = 0;
- this.actindex = 0;
- cr.clearArray(this.temp_parents_arr);
- this.last_event_true = false;
- this.else_branch_ran = false;
- this.any_true_state = false;
- };
- EventStackFrame.prototype.isModifierAfterCnds = function ()
- {
- if (this.current_event.solWriterAfterCnds)
- return true;
- if (this.cndindex < this.current_event.conditions.length - 1)
- return !!this.current_event.solModifiers.length;
- return false;
- };
- cr.eventStackFrame = EventStackFrame;
-}());
-(function()
-{
- function ExpNode(owner_, m)
- {
- this.owner = owner_;
- this.runtime = owner_.runtime;
- this.type = m[0];
-;
- this.get = [this.eval_int,
- this.eval_float,
- this.eval_string,
- this.eval_unaryminus,
- this.eval_add,
- this.eval_subtract,
- this.eval_multiply,
- this.eval_divide,
- this.eval_mod,
- this.eval_power,
- this.eval_and,
- this.eval_or,
- this.eval_equal,
- this.eval_notequal,
- this.eval_less,
- this.eval_lessequal,
- this.eval_greater,
- this.eval_greaterequal,
- this.eval_conditional,
- this.eval_system_exp,
- this.eval_object_exp,
- this.eval_instvar_exp,
- this.eval_behavior_exp,
- this.eval_eventvar_exp][this.type];
- var paramsModel = null;
- this.value = null;
- this.first = null;
- this.second = null;
- this.third = null;
- this.func = null;
- this.results = null;
- this.parameters = null;
- this.object_type = null;
- this.beh_index = -1;
- this.instance_expr = null;
- this.varindex = -1;
- this.behavior_type = null;
- this.varname = null;
- this.eventvar = null;
- this.return_string = false;
- switch (this.type) {
- case 0: // int
- case 1: // float
- case 2: // string
- this.value = m[1];
- break;
- case 3: // unaryminus
- this.first = new cr.expNode(owner_, m[1]);
- break;
- case 18: // conditional
- this.first = new cr.expNode(owner_, m[1]);
- this.second = new cr.expNode(owner_, m[2]);
- this.third = new cr.expNode(owner_, m[3]);
- break;
- case 19: // system_exp
- this.func = this.runtime.GetObjectReference(m[1]);
-;
- if (this.func === cr.system_object.prototype.exps.random
- || this.func === cr.system_object.prototype.exps.choose)
- {
- this.owner.setVaries();
- }
- this.results = [];
- this.parameters = [];
- if (m.length === 3)
- {
- paramsModel = m[2];
- this.results.length = paramsModel.length + 1; // must also fit 'ret'
- }
- else
- this.results.length = 1; // to fit 'ret'
- break;
- case 20: // object_exp
- this.object_type = this.runtime.types_by_index[m[1]];
-;
- this.beh_index = -1;
- this.func = this.runtime.GetObjectReference(m[2]);
- this.return_string = m[3];
- if (cr.plugins_.Function && this.func === cr.plugins_.Function.prototype.exps.Call)
- {
- this.owner.setVaries();
- }
- if (m[4])
- this.instance_expr = new cr.expNode(owner_, m[4]);
- else
- this.instance_expr = null;
- this.results = [];
- this.parameters = [];
- if (m.length === 6)
- {
- paramsModel = m[5];
- this.results.length = paramsModel.length + 1;
- }
- else
- this.results.length = 1; // to fit 'ret'
- break;
- case 21: // instvar_exp
- this.object_type = this.runtime.types_by_index[m[1]];
-;
- this.return_string = m[2];
- if (m[3])
- this.instance_expr = new cr.expNode(owner_, m[3]);
- else
- this.instance_expr = null;
- this.varindex = m[4];
- break;
- case 22: // behavior_exp
- this.object_type = this.runtime.types_by_index[m[1]];
-;
- this.behavior_type = this.object_type.getBehaviorByName(m[2]);
-;
- this.beh_index = this.object_type.getBehaviorIndexByName(m[2]);
- this.func = this.runtime.GetObjectReference(m[3]);
- this.return_string = m[4];
- if (m[5])
- this.instance_expr = new cr.expNode(owner_, m[5]);
- else
- this.instance_expr = null;
- this.results = [];
- this.parameters = [];
- if (m.length === 7)
- {
- paramsModel = m[6];
- this.results.length = paramsModel.length + 1;
- }
- else
- this.results.length = 1; // to fit 'ret'
- break;
- case 23: // eventvar_exp
- this.varname = m[1];
- this.eventvar = null; // assigned in postInit
- break;
- }
- this.owner.maybeVaryForType(this.object_type);
- if (this.type >= 4 && this.type <= 17)
- {
- this.first = new cr.expNode(owner_, m[1]);
- this.second = new cr.expNode(owner_, m[2]);
- }
- if (paramsModel)
- {
- var i, len;
- for (i = 0, len = paramsModel.length; i < len; i++)
- this.parameters.push(new cr.expNode(owner_, paramsModel[i]));
- }
- cr.seal(this);
- };
- ExpNode.prototype.postInit = function ()
- {
- if (this.type === 23) // eventvar_exp
- {
- this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent);
-;
- }
- if (this.first)
- this.first.postInit();
- if (this.second)
- this.second.postInit();
- if (this.third)
- this.third.postInit();
- if (this.instance_expr)
- this.instance_expr.postInit();
- if (this.parameters)
- {
- var i, len;
- for (i = 0, len = this.parameters.length; i < len; i++)
- this.parameters[i].postInit();
- }
- };
- var tempValues = [];
- var tempValuesPtr = -1;
- function pushTempValue()
- {
- ++tempValuesPtr;
- if (tempValues.length === tempValuesPtr)
- tempValues.push(new cr.expvalue());
- return tempValues[tempValuesPtr];
- };
- function popTempValue()
- {
- --tempValuesPtr;
- };
- function eval_params(parameters, results, temp)
- {
- var i, len;
- for (i = 0, len = parameters.length; i < len; ++i)
- {
- parameters[i].get(temp);
- results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue
- }
- }
- ExpNode.prototype.eval_system_exp = function (ret)
- {
- var parameters = this.parameters;
- var results = this.results;
- results[0] = ret;
- var temp = pushTempValue();
- eval_params(parameters, results, temp);
- popTempValue();
- this.func.apply(this.runtime.system, results);
- };
- ExpNode.prototype.eval_object_exp = function (ret)
- {
- var object_type = this.object_type;
- var results = this.results;
- var parameters = this.parameters;
- var instance_expr = this.instance_expr;
- var func = this.func;
- var index = this.owner.solindex; // default to parameter's intended SOL index
- var sol = object_type.getCurrentSol();
- var instances = sol.getObjects();
- if (!instances.length)
- {
- if (sol.else_instances.length)
- instances = sol.else_instances;
- else
- {
- if (this.return_string)
- ret.set_string("");
- else
- ret.set_int(0);
- return;
- }
- }
- results[0] = ret;
- ret.object_class = object_type; // so expression can access family type if need be
- var temp = pushTempValue();
- eval_params(parameters, results, temp);
- if (instance_expr) {
- instance_expr.get(temp);
- if (temp.is_number()) {
- index = temp.data;
- instances = object_type.instances; // pick from all instances, not SOL
- }
- }
- popTempValue();
- var len = instances.length;
- if (index >= len || index <= -len)
- index %= len; // wraparound
- if (index < 0)
- index += len;
- var returned_val = func.apply(instances[index], results);
-;
- };
- ExpNode.prototype.eval_behavior_exp = function (ret)
- {
- var object_type = this.object_type;
- var results = this.results;
- var parameters = this.parameters;
- var instance_expr = this.instance_expr;
- var beh_index = this.beh_index;
- var func = this.func;
- var index = this.owner.solindex; // default to parameter's intended SOL index
- var sol = object_type.getCurrentSol();
- var instances = sol.getObjects();
- if (!instances.length)
- {
- if (sol.else_instances.length)
- instances = sol.else_instances;
- else
- {
- if (this.return_string)
- ret.set_string("");
- else
- ret.set_int(0);
- return;
- }
- }
- results[0] = ret;
- ret.object_class = object_type; // so expression can access family type if need be
- var temp = pushTempValue();
- eval_params(parameters, results, temp);
- if (instance_expr) {
- instance_expr.get(temp);
- if (temp.is_number()) {
- index = temp.data;
- instances = object_type.instances; // pick from all instances, not SOL
- }
- }
- popTempValue();
- var len = instances.length;
- if (index >= len || index <= -len)
- index %= len; // wraparound
- if (index < 0)
- index += len;
- var inst = instances[index];
- var offset = 0;
- if (object_type.is_family)
- {
- offset = inst.type.family_beh_map[object_type.family_index];
- }
- var returned_val = func.apply(inst.behavior_insts[beh_index + offset], results);
-;
- };
- ExpNode.prototype.eval_instvar_exp = function (ret)
- {
- var instance_expr = this.instance_expr;
- var object_type = this.object_type;
- var varindex = this.varindex;
- var index = this.owner.solindex; // default to parameter's intended SOL index
- var sol = object_type.getCurrentSol();
- var instances = sol.getObjects();
- var inst;
- if (!instances.length)
- {
- if (sol.else_instances.length)
- instances = sol.else_instances;
- else
- {
- if (this.return_string)
- ret.set_string("");
- else
- ret.set_int(0);
- return;
- }
- }
- if (instance_expr)
- {
- var temp = pushTempValue();
- instance_expr.get(temp);
- if (temp.is_number())
- {
- index = temp.data;
- var type_instances = object_type.instances;
- if (type_instances.length !== 0) // avoid NaN result with %
- {
- index %= type_instances.length; // wraparound
- if (index < 0) // offset
- index += type_instances.length;
- }
- inst = object_type.getInstanceByIID(index);
- var to_ret = inst.instance_vars[varindex];
- if (cr.is_string(to_ret))
- ret.set_string(to_ret);
- else
- ret.set_float(to_ret);
- popTempValue();
- return; // done
- }
- popTempValue();
- }
- var len = instances.length;
- if (index >= len || index <= -len)
- index %= len; // wraparound
- if (index < 0)
- index += len;
- inst = instances[index];
- var offset = 0;
- if (object_type.is_family)
- {
- offset = inst.type.family_var_map[object_type.family_index];
- }
- var to_ret = inst.instance_vars[varindex + offset];
- if (cr.is_string(to_ret))
- ret.set_string(to_ret);
- else
- ret.set_float(to_ret);
- };
- ExpNode.prototype.eval_int = function (ret)
- {
- ret.type = cr.exptype.Integer;
- ret.data = this.value;
- };
- ExpNode.prototype.eval_float = function (ret)
- {
- ret.type = cr.exptype.Float;
- ret.data = this.value;
- };
- ExpNode.prototype.eval_string = function (ret)
- {
- ret.type = cr.exptype.String;
- ret.data = this.value;
- };
- ExpNode.prototype.eval_unaryminus = function (ret)
- {
- this.first.get(ret); // retrieve operand
- if (ret.is_number())
- ret.data = -ret.data;
- };
- ExpNode.prototype.eval_add = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data += temp.data; // both operands numbers: add
- if (temp.is_float())
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_subtract = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data -= temp.data; // both operands numbers: subtract
- if (temp.is_float())
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_multiply = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data *= temp.data; // both operands numbers: multiply
- if (temp.is_float())
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_divide = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data /= temp.data; // both operands numbers: divide
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_mod = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data %= temp.data; // both operands numbers: modulo
- if (temp.is_float())
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_power = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- ret.data = Math.pow(ret.data, temp.data); // both operands numbers: raise to power
- if (temp.is_float())
- ret.make_float();
- }
- popTempValue();
- };
- ExpNode.prototype.eval_and = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (temp.is_string() || ret.is_string())
- this.eval_and_stringconcat(ret, temp);
- else
- this.eval_and_logical(ret, temp);
- popTempValue();
- };
- ExpNode.prototype.eval_and_stringconcat = function (ret, temp)
- {
- if (ret.is_string() && temp.is_string())
- this.eval_and_stringconcat_str_str(ret, temp);
- else
- this.eval_and_stringconcat_num(ret, temp);
- };
- ExpNode.prototype.eval_and_stringconcat_str_str = function (ret, temp)
- {
- ret.data += temp.data;
- };
- ExpNode.prototype.eval_and_stringconcat_num = function (ret, temp)
- {
- if (ret.is_string())
- {
- ret.data += (Math.round(temp.data * 1e10) / 1e10).toString();
- }
- else
- {
- ret.set_string(ret.data.toString() + temp.data);
- }
- };
- ExpNode.prototype.eval_and_logical = function (ret, temp)
- {
- ret.set_int(ret.data && temp.data ? 1 : 0);
- };
- ExpNode.prototype.eval_or = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- if (ret.is_number() && temp.is_number())
- {
- if (ret.data || temp.data)
- ret.set_int(1);
- else
- ret.set_int(0);
- }
- popTempValue();
- };
- ExpNode.prototype.eval_conditional = function (ret)
- {
- this.first.get(ret); // condition operand
- if (ret.data) // is true
- this.second.get(ret); // evaluate second operand to ret
- else
- this.third.get(ret); // evaluate third operand to ret
- };
- ExpNode.prototype.eval_equal = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data === temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_notequal = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data !== temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_less = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data < temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_lessequal = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data <= temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_greater = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data > temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_greaterequal = function (ret)
- {
- this.first.get(ret); // left operand
- var temp = pushTempValue();
- this.second.get(temp); // right operand
- ret.set_int(ret.data >= temp.data ? 1 : 0);
- popTempValue();
- };
- ExpNode.prototype.eval_eventvar_exp = function (ret)
- {
- var val = this.eventvar.getValue();
- if (cr.is_number(val))
- ret.set_float(val);
- else
- ret.set_string(val);
- };
- cr.expNode = ExpNode;
- function ExpValue(type, data)
- {
- this.type = type || cr.exptype.Integer;
- this.data = data || 0;
- this.object_class = null;
-;
-;
-;
- if (this.type == cr.exptype.Integer)
- this.data = Math.floor(this.data);
- cr.seal(this);
- };
- ExpValue.prototype.is_int = function ()
- {
- return this.type === cr.exptype.Integer;
- };
- ExpValue.prototype.is_float = function ()
- {
- return this.type === cr.exptype.Float;
- };
- ExpValue.prototype.is_number = function ()
- {
- return this.type === cr.exptype.Integer || this.type === cr.exptype.Float;
- };
- ExpValue.prototype.is_string = function ()
- {
- return this.type === cr.exptype.String;
- };
- ExpValue.prototype.make_int = function ()
- {
- if (!this.is_int())
- {
- if (this.is_float())
- this.data = Math.floor(this.data); // truncate float
- else if (this.is_string())
- this.data = parseInt(this.data, 10);
- this.type = cr.exptype.Integer;
- }
- };
- ExpValue.prototype.make_float = function ()
- {
- if (!this.is_float())
- {
- if (this.is_string())
- this.data = parseFloat(this.data);
- this.type = cr.exptype.Float;
- }
- };
- ExpValue.prototype.make_string = function ()
- {
- if (!this.is_string())
- {
- this.data = this.data.toString();
- this.type = cr.exptype.String;
- }
- };
- ExpValue.prototype.set_int = function (val)
- {
-;
- this.type = cr.exptype.Integer;
- this.data = Math.floor(val);
- };
- ExpValue.prototype.set_float = function (val)
- {
-;
- this.type = cr.exptype.Float;
- this.data = val;
- };
- ExpValue.prototype.set_string = function (val)
- {
-;
- this.type = cr.exptype.String;
- this.data = val;
- };
- ExpValue.prototype.set_any = function (val)
- {
- if (cr.is_number(val))
- {
- this.type = cr.exptype.Float;
- this.data = val;
- }
- else if (cr.is_string(val))
- {
- this.type = cr.exptype.String;
- this.data = val.toString();
- }
- else
- {
- this.type = cr.exptype.Integer;
- this.data = 0;
- }
- };
- cr.expvalue = ExpValue;
- cr.exptype = {
- Integer: 0, // emulated; no native integer support in javascript
- Float: 1,
- String: 2
- };
-}());
-;
-cr.system_object = function (runtime)
-{
- this.runtime = runtime;
- this.waits = [];
-};
-cr.system_object.prototype.saveToJSON = function ()
-{
- var o = {};
- var i, len, j, lenj, p, w, t, sobj;
- o["waits"] = [];
- var owaits = o["waits"];
- var waitobj;
- for (i = 0, len = this.waits.length; i < len; i++)
- {
- w = this.waits[i];
- waitobj = {
- "t": w.time,
- "st": w.signaltag,
- "s": w.signalled,
- "ev": w.ev.sid,
- "sm": [],
- "sols": {}
- };
- if (w.ev.actions[w.actindex])
- waitobj["act"] = w.ev.actions[w.actindex].sid;
- for (j = 0, lenj = w.solModifiers.length; j < lenj; j++)
- waitobj["sm"].push(w.solModifiers[j].sid);
- for (p in w.sols)
- {
- if (w.sols.hasOwnProperty(p))
- {
- t = this.runtime.types_by_index[parseInt(p, 10)];
-;
- sobj = {
- "sa": w.sols[p].sa,
- "insts": []
- };
- for (j = 0, lenj = w.sols[p].insts.length; j < lenj; j++)
- sobj["insts"].push(w.sols[p].insts[j].uid);
- waitobj["sols"][t.sid.toString()] = sobj;
- }
- }
- owaits.push(waitobj);
- }
- return o;
-};
-cr.system_object.prototype.loadFromJSON = function (o)
-{
- var owaits = o["waits"];
- var i, len, j, lenj, p, w, addWait, e, aindex, t, savedsol, nusol, inst;
- cr.clearArray(this.waits);
- for (i = 0, len = owaits.length; i < len; i++)
- {
- w = owaits[i];
- e = this.runtime.blocksBySid[w["ev"].toString()];
- if (!e)
- continue; // event must've gone missing
- aindex = -1;
- for (j = 0, lenj = e.actions.length; j < lenj; j++)
- {
- if (e.actions[j].sid === w["act"])
- {
- aindex = j;
- break;
- }
- }
- if (aindex === -1)
- continue; // action must've gone missing
- addWait = {};
- addWait.sols = {};
- addWait.solModifiers = [];
- addWait.deleteme = false;
- addWait.time = w["t"];
- addWait.signaltag = w["st"] || "";
- addWait.signalled = !!w["s"];
- addWait.ev = e;
- addWait.actindex = aindex;
- for (j = 0, lenj = w["sm"].length; j < lenj; j++)
- {
- t = this.runtime.getObjectTypeBySid(w["sm"][j]);
- if (t)
- addWait.solModifiers.push(t);
- }
- for (p in w["sols"])
- {
- if (w["sols"].hasOwnProperty(p))
- {
- t = this.runtime.getObjectTypeBySid(parseInt(p, 10));
- if (!t)
- continue; // type must've been deleted
- savedsol = w["sols"][p];
- nusol = {
- sa: savedsol["sa"],
- insts: []
- };
- for (j = 0, lenj = savedsol["insts"].length; j < lenj; j++)
- {
- inst = this.runtime.getObjectByUID(savedsol["insts"][j]);
- if (inst)
- nusol.insts.push(inst);
- }
- addWait.sols[t.index.toString()] = nusol;
- }
- }
- this.waits.push(addWait);
- }
-};
-(function ()
-{
- var sysProto = cr.system_object.prototype;
- function SysCnds() {};
- SysCnds.prototype.EveryTick = function()
- {
- return true;
- };
- SysCnds.prototype.OnLayoutStart = function()
- {
- return true;
- };
- SysCnds.prototype.OnLayoutEnd = function()
- {
- return true;
- };
- SysCnds.prototype.Compare = function(x, cmp, y)
- {
- return cr.do_cmp(x, cmp, y);
- };
- SysCnds.prototype.CompareTime = function (cmp, t)
- {
- var elapsed = this.runtime.kahanTime.sum;
- if (cmp === 0)
- {
- var cnd = this.runtime.getCurrentCondition();
- if (!cnd.extra["CompareTime_executed"])
- {
- if (elapsed >= t)
- {
- cnd.extra["CompareTime_executed"] = true;
- return true;
- }
- }
- return false;
- }
- return cr.do_cmp(elapsed, cmp, t);
- };
- SysCnds.prototype.LayerVisible = function (layer)
- {
- if (!layer)
- return false;
- else
- return layer.visible;
- };
- SysCnds.prototype.LayerEmpty = function (layer)
- {
- if (!layer)
- return false;
- else
- return !layer.instances.length;
- };
- SysCnds.prototype.LayerCmpOpacity = function (layer, cmp, opacity_)
- {
- if (!layer)
- return false;
- return cr.do_cmp(layer.opacity * 100, cmp, opacity_);
- };
- SysCnds.prototype.Repeat = function (count)
- {
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var solModifierAfterCnds = current_frame.isModifierAfterCnds();
- var current_loop = this.runtime.pushLoopStack();
- var i;
- if (solModifierAfterCnds)
- {
- for (i = 0; i < count && !current_loop.stopped; i++)
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- current_loop.index = i;
- current_event.retrigger();
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- for (i = 0; i < count && !current_loop.stopped; i++)
- {
- current_loop.index = i;
- current_event.retrigger();
- }
- }
- this.runtime.popLoopStack();
- return false;
- };
- SysCnds.prototype.While = function (count)
- {
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var solModifierAfterCnds = current_frame.isModifierAfterCnds();
- var current_loop = this.runtime.pushLoopStack();
- var i;
- if (solModifierAfterCnds)
- {
- for (i = 0; !current_loop.stopped; i++)
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- current_loop.index = i;
- if (!current_event.retrigger()) // one of the other conditions returned false
- current_loop.stopped = true; // break
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- for (i = 0; !current_loop.stopped; i++)
- {
- current_loop.index = i;
- if (!current_event.retrigger())
- current_loop.stopped = true;
- }
- }
- this.runtime.popLoopStack();
- return false;
- };
- SysCnds.prototype.For = function (name, start, end)
- {
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var solModifierAfterCnds = current_frame.isModifierAfterCnds();
- var current_loop = this.runtime.pushLoopStack(name);
- var i;
- if (end < start)
- {
- if (solModifierAfterCnds)
- {
- for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- current_loop.index = i;
- current_event.retrigger();
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
- {
- current_loop.index = i;
- current_event.retrigger();
- }
- }
- }
- else
- {
- if (solModifierAfterCnds)
- {
- for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- current_loop.index = i;
- current_event.retrigger();
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
- {
- current_loop.index = i;
- current_event.retrigger();
- }
- }
- }
- this.runtime.popLoopStack();
- return false;
- };
- var foreach_instancestack = [];
- var foreach_instanceptr = -1;
- SysCnds.prototype.ForEach = function (obj)
- {
- var sol = obj.getCurrentSol();
- foreach_instanceptr++;
- if (foreach_instancestack.length === foreach_instanceptr)
- foreach_instancestack.push([]);
- var instances = foreach_instancestack[foreach_instanceptr];
- cr.shallowAssignArray(instances, sol.getObjects());
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var solModifierAfterCnds = current_frame.isModifierAfterCnds();
- var current_loop = this.runtime.pushLoopStack();
- var i, len, j, lenj, inst, s, sol2;
- var is_contained = obj.is_contained;
- if (solModifierAfterCnds)
- {
- for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- inst = instances[i];
- sol = obj.getCurrentSol();
- sol.select_all = false;
- cr.clearArray(sol.instances);
- sol.instances[0] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- sol2 = s.type.getCurrentSol();
- sol2.select_all = false;
- cr.clearArray(sol2.instances);
- sol2.instances[0] = s;
- }
- }
- current_loop.index = i;
- current_event.retrigger();
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- sol.select_all = false;
- cr.clearArray(sol.instances);
- for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
- {
- inst = instances[i];
- sol.instances[0] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- sol2 = s.type.getCurrentSol();
- sol2.select_all = false;
- cr.clearArray(sol2.instances);
- sol2.instances[0] = s;
- }
- }
- current_loop.index = i;
- current_event.retrigger();
- }
- }
- cr.clearArray(instances);
- this.runtime.popLoopStack();
- foreach_instanceptr--;
- return false;
- };
- function foreach_sortinstances(a, b)
- {
- var va = a.extra["c2_feo_val"];
- var vb = b.extra["c2_feo_val"];
- if (cr.is_number(va) && cr.is_number(vb))
- return va - vb;
- else
- {
- va = "" + va;
- vb = "" + vb;
- if (va < vb)
- return -1;
- else if (va > vb)
- return 1;
- else
- return 0;
- }
- };
- SysCnds.prototype.ForEachOrdered = function (obj, exp, order)
- {
- var sol = obj.getCurrentSol();
- foreach_instanceptr++;
- if (foreach_instancestack.length === foreach_instanceptr)
- foreach_instancestack.push([]);
- var instances = foreach_instancestack[foreach_instanceptr];
- cr.shallowAssignArray(instances, sol.getObjects());
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var current_condition = this.runtime.getCurrentCondition();
- var solModifierAfterCnds = current_frame.isModifierAfterCnds();
- var current_loop = this.runtime.pushLoopStack();
- var i, len, j, lenj, inst, s, sol2;
- for (i = 0, len = instances.length; i < len; i++)
- {
- instances[i].extra["c2_feo_val"] = current_condition.parameters[1].get(i);
- }
- instances.sort(foreach_sortinstances);
- if (order === 1)
- instances.reverse();
- var is_contained = obj.is_contained;
- if (solModifierAfterCnds)
- {
- for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
- {
- this.runtime.pushCopySol(current_event.solModifiers);
- inst = instances[i];
- sol = obj.getCurrentSol();
- sol.select_all = false;
- cr.clearArray(sol.instances);
- sol.instances[0] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- sol2 = s.type.getCurrentSol();
- sol2.select_all = false;
- cr.clearArray(sol2.instances);
- sol2.instances[0] = s;
- }
- }
- current_loop.index = i;
- current_event.retrigger();
- this.runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- sol.select_all = false;
- cr.clearArray(sol.instances);
- for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
- {
- inst = instances[i];
- sol.instances[0] = inst;
- if (is_contained)
- {
- for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
- {
- s = inst.siblings[j];
- sol2 = s.type.getCurrentSol();
- sol2.select_all = false;
- cr.clearArray(sol2.instances);
- sol2.instances[0] = s;
- }
- }
- current_loop.index = i;
- current_event.retrigger();
- }
- }
- cr.clearArray(instances);
- this.runtime.popLoopStack();
- foreach_instanceptr--;
- return false;
- };
- SysCnds.prototype.PickByComparison = function (obj_, exp_, cmp_, val_)
- {
- var i, len, k, inst;
- if (!obj_)
- return;
- foreach_instanceptr++;
- if (foreach_instancestack.length === foreach_instanceptr)
- foreach_instancestack.push([]);
- var tmp_instances = foreach_instancestack[foreach_instanceptr];
- var sol = obj_.getCurrentSol();
- cr.shallowAssignArray(tmp_instances, sol.getObjects());
- if (sol.select_all)
- cr.clearArray(sol.else_instances);
- var current_condition = this.runtime.getCurrentCondition();
- for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
- {
- inst = tmp_instances[i];
- tmp_instances[k] = inst;
- exp_ = current_condition.parameters[1].get(i);
- val_ = current_condition.parameters[3].get(i);
- if (cr.do_cmp(exp_, cmp_, val_))
- {
- k++;
- }
- else
- {
- sol.else_instances.push(inst);
- }
- }
- cr.truncateArray(tmp_instances, k);
- sol.select_all = false;
- cr.shallowAssignArray(sol.instances, tmp_instances);
- cr.clearArray(tmp_instances);
- foreach_instanceptr--;
- obj_.applySolToContainer();
- return !!sol.instances.length;
- };
- SysCnds.prototype.PickByEvaluate = function (obj_, exp_)
- {
- var i, len, k, inst;
- if (!obj_)
- return;
- foreach_instanceptr++;
- if (foreach_instancestack.length === foreach_instanceptr)
- foreach_instancestack.push([]);
- var tmp_instances = foreach_instancestack[foreach_instanceptr];
- var sol = obj_.getCurrentSol();
- cr.shallowAssignArray(tmp_instances, sol.getObjects());
- if (sol.select_all)
- cr.clearArray(sol.else_instances);
- var current_condition = this.runtime.getCurrentCondition();
- for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
- {
- inst = tmp_instances[i];
- tmp_instances[k] = inst;
- exp_ = current_condition.parameters[1].get(i);
- if (exp_)
- {
- k++;
- }
- else
- {
- sol.else_instances.push(inst);
- }
- }
- cr.truncateArray(tmp_instances, k);
- sol.select_all = false;
- cr.shallowAssignArray(sol.instances, tmp_instances);
- cr.clearArray(tmp_instances);
- foreach_instanceptr--;
- obj_.applySolToContainer();
- return !!sol.instances.length;
- };
- SysCnds.prototype.TriggerOnce = function ()
- {
- var cndextra = this.runtime.getCurrentCondition().extra;
- if (typeof cndextra["TriggerOnce_lastTick"] === "undefined")
- cndextra["TriggerOnce_lastTick"] = -1;
- var last_tick = cndextra["TriggerOnce_lastTick"];
- var cur_tick = this.runtime.tickcount;
- cndextra["TriggerOnce_lastTick"] = cur_tick;
- return this.runtime.layout_first_tick || last_tick !== cur_tick - 1;
- };
- SysCnds.prototype.Every = function (seconds)
- {
- var cnd = this.runtime.getCurrentCondition();
- var last_time = cnd.extra["Every_lastTime"] || 0;
- var cur_time = this.runtime.kahanTime.sum;
- if (typeof cnd.extra["Every_seconds"] === "undefined")
- cnd.extra["Every_seconds"] = seconds;
- var this_seconds = cnd.extra["Every_seconds"];
- if (cur_time >= last_time + this_seconds)
- {
- cnd.extra["Every_lastTime"] = last_time + this_seconds;
- if (cur_time >= cnd.extra["Every_lastTime"] + 0.04)
- {
- cnd.extra["Every_lastTime"] = cur_time;
- }
- cnd.extra["Every_seconds"] = seconds;
- return true;
- }
- else if (cur_time < last_time - 0.1)
- {
- cnd.extra["Every_lastTime"] = cur_time;
- }
- return false;
- };
- SysCnds.prototype.PickNth = function (obj, index)
- {
- if (!obj)
- return false;
- var sol = obj.getCurrentSol();
- var instances = sol.getObjects();
- index = cr.floor(index);
- if (index < 0 || index >= instances.length)
- return false;
- var inst = instances[index];
- sol.pick_one(inst);
- obj.applySolToContainer();
- return true;
- };
- SysCnds.prototype.PickRandom = function (obj)
- {
- if (!obj)
- return false;
- var sol = obj.getCurrentSol();
- var instances = sol.getObjects();
- var index = cr.floor(Math.random() * instances.length);
- if (index >= instances.length)
- return false;
- var inst = instances[index];
- sol.pick_one(inst);
- obj.applySolToContainer();
- return true;
- };
- SysCnds.prototype.CompareVar = function (v, cmp, val)
- {
- return cr.do_cmp(v.getValue(), cmp, val);
- };
- SysCnds.prototype.IsGroupActive = function (group)
- {
- var g = this.runtime.groups_by_name[group.toLowerCase()];
- return g && g.group_active;
- };
- SysCnds.prototype.IsPreview = function ()
- {
- return typeof cr_is_preview !== "undefined";
- };
- SysCnds.prototype.PickAll = function (obj)
- {
- if (!obj)
- return false;
- if (!obj.instances.length)
- return false;
- var sol = obj.getCurrentSol();
- sol.select_all = true;
- obj.applySolToContainer();
- return true;
- };
- SysCnds.prototype.IsMobile = function ()
- {
- return this.runtime.isMobile;
- };
- SysCnds.prototype.CompareBetween = function (x, a, b)
- {
- return x >= a && x <= b;
- };
- SysCnds.prototype.Else = function ()
- {
- var current_frame = this.runtime.getCurrentEventStack();
- if (current_frame.else_branch_ran)
- return false; // another event in this else-if chain has run
- else
- return !current_frame.last_event_true;
- /*
- var current_frame = this.runtime.getCurrentEventStack();
- var current_event = current_frame.current_event;
- var prev_event = current_event.prev_block;
- if (!prev_event)
- return false;
- if (prev_event.is_logical)
- return !this.runtime.last_event_true;
- var i, len, j, lenj, s, sol, temp, inst, any_picked = false;
- for (i = 0, len = prev_event.cndReferences.length; i < len; i++)
- {
- s = prev_event.cndReferences[i];
- sol = s.getCurrentSol();
- if (sol.select_all || sol.instances.length === s.instances.length)
- {
- sol.select_all = false;
- sol.instances.length = 0;
- }
- else
- {
- if (sol.instances.length === 1 && sol.else_instances.length === 0 && s.instances.length >= 2)
- {
- inst = sol.instances[0];
- sol.instances.length = 0;
- for (j = 0, lenj = s.instances.length; j < lenj; j++)
- {
- if (s.instances[j] != inst)
- sol.instances.push(s.instances[j]);
- }
- any_picked = true;
- }
- else
- {
- temp = sol.instances;
- sol.instances = sol.else_instances;
- sol.else_instances = temp;
- any_picked = true;
- }
- }
- }
- return any_picked;
- */
- };
- SysCnds.prototype.OnLoadFinished = function ()
- {
- return true;
- };
- SysCnds.prototype.OnCanvasSnapshot = function ()
- {
- return true;
- };
- SysCnds.prototype.EffectsSupported = function ()
- {
- return !!this.runtime.glwrap;
- };
- SysCnds.prototype.OnSaveComplete = function ()
- {
- return true;
- };
- SysCnds.prototype.OnSaveFailed = function ()
- {
- return true;
- };
- SysCnds.prototype.OnLoadComplete = function ()
- {
- return true;
- };
- SysCnds.prototype.OnLoadFailed = function ()
- {
- return true;
- };
- SysCnds.prototype.ObjectUIDExists = function (u)
- {
- return !!this.runtime.getObjectByUID(u);
- };
- SysCnds.prototype.IsOnPlatform = function (p)
- {
- var rt = this.runtime;
- switch (p) {
- case 0: // HTML5 website
- return !rt.isDomFree && !rt.isNodeWebkit && !rt.isCordova && !rt.isWinJS && !rt.isWindowsPhone8 && !rt.isBlackberry10 && !rt.isAmazonWebApp;
- case 1: // iOS
- return rt.isiOS;
- case 2: // Android
- return rt.isAndroid;
- case 3: // Windows 8
- return rt.isWindows8App;
- case 4: // Windows Phone 8
- return rt.isWindowsPhone8;
- case 5: // Blackberry 10
- return rt.isBlackberry10;
- case 6: // Tizen
- return rt.isTizen;
- case 7: // CocoonJS
- return rt.isCocoonJs;
- case 8: // Cordova
- return rt.isCordova;
- case 9: // Scirra Arcade
- return rt.isArcade;
- case 10: // node-webkit
- return rt.isNodeWebkit;
- case 11: // crosswalk
- return rt.isCrosswalk;
- case 12: // amazon webapp
- return rt.isAmazonWebApp;
- case 13: // windows 10 app
- return rt.isWindows10;
- default: // should not be possible
- return false;
- }
- };
- var cacheRegex = null;
- var lastRegex = "";
- var lastFlags = "";
- function getRegex(regex_, flags_)
- {
- if (!cacheRegex || regex_ !== lastRegex || flags_ !== lastFlags)
- {
- cacheRegex = new RegExp(regex_, flags_);
- lastRegex = regex_;
- lastFlags = flags_;
- }
- cacheRegex.lastIndex = 0; // reset
- return cacheRegex;
- };
- SysCnds.prototype.RegexTest = function (str_, regex_, flags_)
- {
- var regex = getRegex(regex_, flags_);
- return regex.test(str_);
- };
- var tmp_arr = [];
- SysCnds.prototype.PickOverlappingPoint = function (obj_, x_, y_)
- {
- if (!obj_)
- return false;
- var sol = obj_.getCurrentSol();
- var instances = sol.getObjects();
- var current_event = this.runtime.getCurrentEventStack().current_event;
- var orblock = current_event.orblock;
- var cnd = this.runtime.getCurrentCondition();
- var i, len, inst, pick;
- if (sol.select_all)
- {
- cr.shallowAssignArray(tmp_arr, instances);
- cr.clearArray(sol.else_instances);
- sol.select_all = false;
- cr.clearArray(sol.instances);
- }
- else
- {
- if (orblock)
- {
- cr.shallowAssignArray(tmp_arr, sol.else_instances);
- cr.clearArray(sol.else_instances);
- }
- else
- {
- cr.shallowAssignArray(tmp_arr, instances);
- cr.clearArray(sol.instances);
- }
- }
- for (i = 0, len = tmp_arr.length; i < len; ++i)
- {
- inst = tmp_arr[i];
- inst.update_bbox();
- pick = cr.xor(inst.contains_pt(x_, y_), cnd.inverted);
- if (pick)
- sol.instances.push(inst);
- else
- sol.else_instances.push(inst);
- }
- obj_.applySolToContainer();
- return cr.xor(!!sol.instances.length, cnd.inverted);
- };
- SysCnds.prototype.IsNaN = function (n)
- {
- return !!isNaN(n);
- };
- SysCnds.prototype.AngleWithin = function (a1, within, a2)
- {
- return cr.angleDiff(cr.to_radians(a1), cr.to_radians(a2)) <= cr.to_radians(within);
- };
- SysCnds.prototype.IsClockwiseFrom = function (a1, a2)
- {
- return cr.angleClockwise(cr.to_radians(a1), cr.to_radians(a2));
- };
- SysCnds.prototype.IsBetweenAngles = function (a, la, ua)
- {
- var angle = cr.to_clamped_radians(a);
- var lower = cr.to_clamped_radians(la);
- var upper = cr.to_clamped_radians(ua);
- var obtuse = (!cr.angleClockwise(upper, lower));
- if (obtuse)
- return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
- else
- return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
- };
- SysCnds.prototype.IsValueType = function (x, t)
- {
- if (typeof x === "number")
- return t === 0;
- else // string
- return t === 1;
- };
- sysProto.cnds = new SysCnds();
- function SysActs() {};
- SysActs.prototype.GoToLayout = function (to)
- {
- if (this.runtime.isloading)
- return; // cannot change layout while loading on loader layout
- if (this.runtime.changelayout)
- return; // already changing to a different layout
-;
- this.runtime.changelayout = to;
- };
- SysActs.prototype.NextPrevLayout = function (prev)
- {
- if (this.runtime.isloading)
- return; // cannot change layout while loading on loader layout
- if (this.runtime.changelayout)
- return; // already changing to a different layout
- var index = this.runtime.layouts_by_index.indexOf(this.runtime.running_layout);
- if (prev && index === 0)
- return; // cannot go to previous layout from first layout
- if (!prev && index === this.runtime.layouts_by_index.length - 1)
- return; // cannot go to next layout from last layout
- var to = this.runtime.layouts_by_index[index + (prev ? -1 : 1)];
-;
- this.runtime.changelayout = to;
- };
- SysActs.prototype.CreateObject = function (obj, layer, x, y)
- {
- if (!layer || !obj)
- return;
- var inst = this.runtime.createInstance(obj, layer, x, y);
- if (!inst)
- return;
- this.runtime.isInOnDestroy++;
- var i, len, s;
- this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
- if (inst.is_contained)
- {
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- s = inst.siblings[i];
- this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
- }
- }
- this.runtime.isInOnDestroy--;
- var sol = obj.getCurrentSol();
- sol.select_all = false;
- cr.clearArray(sol.instances);
- sol.instances[0] = inst;
- if (inst.is_contained)
- {
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- s = inst.siblings[i];
- sol = s.type.getCurrentSol();
- sol.select_all = false;
- cr.clearArray(sol.instances);
- sol.instances[0] = s;
- }
- }
- };
- SysActs.prototype.SetLayerVisible = function (layer, visible_)
- {
- if (!layer)
- return;
- if (layer.visible !== visible_)
- {
- layer.visible = visible_;
- this.runtime.redraw = true;
- }
- };
- SysActs.prototype.SetLayerOpacity = function (layer, opacity_)
- {
- if (!layer)
- return;
- opacity_ = cr.clamp(opacity_ / 100, 0, 1);
- if (layer.opacity !== opacity_)
- {
- layer.opacity = opacity_;
- this.runtime.redraw = true;
- }
- };
- SysActs.prototype.SetLayerScaleRate = function (layer, sr)
- {
- if (!layer)
- return;
- if (layer.zoomRate !== sr)
- {
- layer.zoomRate = sr;
- this.runtime.redraw = true;
- }
- };
- SysActs.prototype.SetLayerForceOwnTexture = function (layer, f)
- {
- if (!layer)
- return;
- f = !!f;
- if (layer.forceOwnTexture !== f)
- {
- layer.forceOwnTexture = f;
- this.runtime.redraw = true;
- }
- };
- SysActs.prototype.SetLayoutScale = function (s)
- {
- if (!this.runtime.running_layout)
- return;
- if (this.runtime.running_layout.scale !== s)
- {
- this.runtime.running_layout.scale = s;
- this.runtime.running_layout.boundScrolling();
- this.runtime.redraw = true;
- }
- };
- SysActs.prototype.ScrollX = function(x)
- {
- this.runtime.running_layout.scrollToX(x);
- };
- SysActs.prototype.ScrollY = function(y)
- {
- this.runtime.running_layout.scrollToY(y);
- };
- SysActs.prototype.Scroll = function(x, y)
- {
- this.runtime.running_layout.scrollToX(x);
- this.runtime.running_layout.scrollToY(y);
- };
- SysActs.prototype.ScrollToObject = function(obj)
- {
- var inst = obj.getFirstPicked();
- if (inst)
- {
- this.runtime.running_layout.scrollToX(inst.x);
- this.runtime.running_layout.scrollToY(inst.y);
- }
- };
- SysActs.prototype.SetVar = function(v, x)
- {
-;
- if (v.vartype === 0)
- {
- if (cr.is_number(x))
- v.setValue(x);
- else
- v.setValue(parseFloat(x));
- }
- else if (v.vartype === 1)
- v.setValue(x.toString());
- };
- SysActs.prototype.AddVar = function(v, x)
- {
-;
- if (v.vartype === 0)
- {
- if (cr.is_number(x))
- v.setValue(v.getValue() + x);
- else
- v.setValue(v.getValue() + parseFloat(x));
- }
- else if (v.vartype === 1)
- v.setValue(v.getValue() + x.toString());
- };
- SysActs.prototype.SubVar = function(v, x)
- {
-;
- if (v.vartype === 0)
- {
- if (cr.is_number(x))
- v.setValue(v.getValue() - x);
- else
- v.setValue(v.getValue() - parseFloat(x));
- }
- };
- SysActs.prototype.SetGroupActive = function (group, active)
- {
- var g = this.runtime.groups_by_name[group.toLowerCase()];
- if (!g)
- return;
- switch (active) {
- case 0:
- g.setGroupActive(false);
- break;
- case 1:
- g.setGroupActive(true);
- break;
- case 2:
- g.setGroupActive(!g.group_active);
- break;
- }
- };
- SysActs.prototype.SetTimescale = function (ts_)
- {
- var ts = ts_;
- if (ts < 0)
- ts = 0;
- this.runtime.timescale = ts;
- };
- SysActs.prototype.SetObjectTimescale = function (obj, ts_)
- {
- var ts = ts_;
- if (ts < 0)
- ts = 0;
- if (!obj)
- return;
- var sol = obj.getCurrentSol();
- var instances = sol.getObjects();
- var i, len;
- for (i = 0, len = instances.length; i < len; i++)
- {
- instances[i].my_timescale = ts;
- }
- };
- SysActs.prototype.RestoreObjectTimescale = function (obj)
- {
- if (!obj)
- return false;
- var sol = obj.getCurrentSol();
- var instances = sol.getObjects();
- var i, len;
- for (i = 0, len = instances.length; i < len; i++)
- {
- instances[i].my_timescale = -1.0;
- }
- };
- var waitobjrecycle = [];
- function allocWaitObject()
- {
- var w;
- if (waitobjrecycle.length)
- w = waitobjrecycle.pop();
- else
- {
- w = {};
- w.sols = {};
- w.solModifiers = [];
- }
- w.deleteme = false;
- return w;
- };
- function freeWaitObject(w)
- {
- cr.wipe(w.sols);
- cr.clearArray(w.solModifiers);
- waitobjrecycle.push(w);
- };
- var solstateobjects = [];
- function allocSolStateObject()
- {
- var s;
- if (solstateobjects.length)
- s = solstateobjects.pop();
- else
- {
- s = {};
- s.insts = [];
- }
- s.sa = false;
- return s;
- };
- function freeSolStateObject(s)
- {
- cr.clearArray(s.insts);
- solstateobjects.push(s);
- };
- SysActs.prototype.Wait = function (seconds)
- {
- if (seconds < 0)
- return;
- var i, len, s, t, ss;
- var evinfo = this.runtime.getCurrentEventStack();
- var waitobj = allocWaitObject();
- waitobj.time = this.runtime.kahanTime.sum + seconds;
- waitobj.signaltag = "";
- waitobj.signalled = false;
- waitobj.ev = evinfo.current_event;
- waitobj.actindex = evinfo.actindex + 1; // pointing at next action
- for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
- {
- t = this.runtime.types_by_index[i];
- s = t.getCurrentSol();
- if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
- continue;
- waitobj.solModifiers.push(t);
- ss = allocSolStateObject();
- ss.sa = s.select_all;
- cr.shallowAssignArray(ss.insts, s.instances);
- waitobj.sols[i.toString()] = ss;
- }
- this.waits.push(waitobj);
- return true;
- };
- SysActs.prototype.WaitForSignal = function (tag)
- {
- var i, len, s, t, ss;
- var evinfo = this.runtime.getCurrentEventStack();
- var waitobj = allocWaitObject();
- waitobj.time = -1;
- waitobj.signaltag = tag.toLowerCase();
- waitobj.signalled = false;
- waitobj.ev = evinfo.current_event;
- waitobj.actindex = evinfo.actindex + 1; // pointing at next action
- for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
- {
- t = this.runtime.types_by_index[i];
- s = t.getCurrentSol();
- if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
- continue;
- waitobj.solModifiers.push(t);
- ss = allocSolStateObject();
- ss.sa = s.select_all;
- cr.shallowAssignArray(ss.insts, s.instances);
- waitobj.sols[i.toString()] = ss;
- }
- this.waits.push(waitobj);
- return true;
- };
- SysActs.prototype.Signal = function (tag)
- {
- var lowertag = tag.toLowerCase();
- var i, len, w;
- for (i = 0, len = this.waits.length; i < len; ++i)
- {
- w = this.waits[i];
- if (w.time !== -1)
- continue; // timer wait, ignore
- if (w.signaltag === lowertag) // waiting for this signal
- w.signalled = true; // will run on next check
- }
- };
- SysActs.prototype.SetLayerScale = function (layer, scale)
- {
- if (!layer)
- return;
- if (layer.scale === scale)
- return;
- layer.scale = scale;
- this.runtime.redraw = true;
- };
- SysActs.prototype.ResetGlobals = function ()
- {
- var i, len, g;
- for (i = 0, len = this.runtime.all_global_vars.length; i < len; i++)
- {
- g = this.runtime.all_global_vars[i];
- g.data = g.initial;
- }
- };
- SysActs.prototype.SetLayoutAngle = function (a)
- {
- a = cr.to_radians(a);
- a = cr.clamp_angle(a);
- if (this.runtime.running_layout)
- {
- if (this.runtime.running_layout.angle !== a)
- {
- this.runtime.running_layout.angle = a;
- this.runtime.redraw = true;
- }
- }
- };
- SysActs.prototype.SetLayerAngle = function (layer, a)
- {
- if (!layer)
- return;
- a = cr.to_radians(a);
- a = cr.clamp_angle(a);
- if (layer.angle === a)
- return;
- layer.angle = a;
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerParallax = function (layer, px, py)
- {
- if (!layer)
- return;
- if (layer.parallaxX === px / 100 && layer.parallaxY === py / 100)
- return;
- layer.parallaxX = px / 100;
- layer.parallaxY = py / 100;
- if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
- {
- var i, len, instances = layer.instances;
- for (i = 0, len = instances.length; i < len; ++i)
- {
- instances[i].type.any_instance_parallaxed = true;
- }
- }
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerBackground = function (layer, c)
- {
- if (!layer)
- return;
- var r = cr.GetRValue(c);
- var g = cr.GetGValue(c);
- var b = cr.GetBValue(c);
- if (layer.background_color[0] === r && layer.background_color[1] === g && layer.background_color[2] === b)
- return;
- layer.background_color[0] = r;
- layer.background_color[1] = g;
- layer.background_color[2] = b;
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerTransparent = function (layer, t)
- {
- if (!layer)
- return;
- if (!!t === !!layer.transparent)
- return;
- layer.transparent = !!t;
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerBlendMode = function (layer, bm)
- {
- if (!layer)
- return;
- if (layer.blend_mode === bm)
- return;
- layer.blend_mode = bm;
- layer.compositeOp = cr.effectToCompositeOp(layer.blend_mode);
- if (this.runtime.gl)
- cr.setGLBlend(layer, layer.blend_mode, this.runtime.gl);
- this.runtime.redraw = true;
- };
- SysActs.prototype.StopLoop = function ()
- {
- if (this.runtime.loop_stack_index < 0)
- return; // no loop currently running
- this.runtime.getCurrentLoop().stopped = true;
- };
- SysActs.prototype.GoToLayoutByName = function (layoutname)
- {
- if (this.runtime.isloading)
- return; // cannot change layout while loading on loader layout
- if (this.runtime.changelayout)
- return; // already changing to different layout
-;
- var l;
- for (l in this.runtime.layouts)
- {
- if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutname))
- {
- this.runtime.changelayout = this.runtime.layouts[l];
- return;
- }
- }
- };
- SysActs.prototype.RestartLayout = function (layoutname)
- {
- if (this.runtime.isloading)
- return; // cannot restart loader layouts
- if (this.runtime.changelayout)
- return; // already changing to a different layout
-;
- if (!this.runtime.running_layout)
- return;
- this.runtime.changelayout = this.runtime.running_layout;
- var i, len, g;
- for (i = 0, len = this.runtime.allGroups.length; i < len; i++)
- {
- g = this.runtime.allGroups[i];
- g.setGroupActive(g.initially_activated);
- }
- };
- SysActs.prototype.SnapshotCanvas = function (format_, quality_)
- {
- this.runtime.doCanvasSnapshot(format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100);
- };
- SysActs.prototype.SetCanvasSize = function (w, h)
- {
- if (w <= 0 || h <= 0)
- return;
- var mode = this.runtime.fullscreen_mode;
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
- if (isfullscreen && this.runtime.fullscreen_scaling > 0)
- mode = this.runtime.fullscreen_scaling;
- if (mode === 0)
- {
- this.runtime["setSize"](w, h, true);
- }
- else
- {
- this.runtime.original_width = w;
- this.runtime.original_height = h;
- this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
- }
- };
- SysActs.prototype.SetLayoutEffectEnabled = function (enable_, effectname_)
- {
- if (!this.runtime.running_layout || !this.runtime.glwrap)
- return;
- var et = this.runtime.running_layout.getEffectByName(effectname_);
- if (!et)
- return; // effect name not found
- var enable = (enable_ === 1);
- if (et.active == enable)
- return; // no change
- et.active = enable;
- this.runtime.running_layout.updateActiveEffects();
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerEffectEnabled = function (layer, enable_, effectname_)
- {
- if (!layer || !this.runtime.glwrap)
- return;
- var et = layer.getEffectByName(effectname_);
- if (!et)
- return; // effect name not found
- var enable = (enable_ === 1);
- if (et.active == enable)
- return; // no change
- et.active = enable;
- layer.updateActiveEffects();
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayoutEffectParam = function (effectname_, index_, value_)
- {
- if (!this.runtime.running_layout || !this.runtime.glwrap)
- return;
- var et = this.runtime.running_layout.getEffectByName(effectname_);
- if (!et)
- return; // effect name not found
- var params = this.runtime.running_layout.effect_params[et.index];
- index_ = Math.floor(index_);
- if (index_ < 0 || index_ >= params.length)
- return; // effect index out of bounds
- if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
- value_ /= 100.0;
- if (params[index_] === value_)
- return; // no change
- params[index_] = value_;
- if (et.active)
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetLayerEffectParam = function (layer, effectname_, index_, value_)
- {
- if (!layer || !this.runtime.glwrap)
- return;
- var et = layer.getEffectByName(effectname_);
- if (!et)
- return; // effect name not found
- var params = layer.effect_params[et.index];
- index_ = Math.floor(index_);
- if (index_ < 0 || index_ >= params.length)
- return; // effect index out of bounds
- if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
- value_ /= 100.0;
- if (params[index_] === value_)
- return; // no change
- params[index_] = value_;
- if (et.active)
- this.runtime.redraw = true;
- };
- SysActs.prototype.SaveState = function (slot_)
- {
- this.runtime.saveToSlot = slot_;
- };
- SysActs.prototype.LoadState = function (slot_)
- {
- this.runtime.loadFromSlot = slot_;
- };
- SysActs.prototype.LoadStateJSON = function (jsonstr_)
- {
- this.runtime.loadFromJson = jsonstr_;
- };
- SysActs.prototype.SetHalfFramerateMode = function (set_)
- {
- this.runtime.halfFramerateMode = (set_ !== 0);
- };
- SysActs.prototype.SetFullscreenQuality = function (q)
- {
- var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen);
- if (!isfullscreen && this.runtime.fullscreen_mode === 0)
- return;
- this.runtime.wantFullscreenScalingQuality = (q !== 0);
- this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
- };
- SysActs.prototype.ResetPersisted = function ()
- {
- var i, len;
- for (i = 0, len = this.runtime.layouts_by_index.length; i < len; ++i)
- {
- this.runtime.layouts_by_index[i].persist_data = {};
- this.runtime.layouts_by_index[i].first_visit = true;
- }
- };
- SysActs.prototype.RecreateInitialObjects = function (obj, x1, y1, x2, y2)
- {
- if (!obj)
- return;
- this.runtime.running_layout.recreateInitialObjects(obj, x1, y1, x2, y2);
- };
- SysActs.prototype.SetPixelRounding = function (m)
- {
- this.runtime.pixel_rounding = (m !== 0);
- this.runtime.redraw = true;
- };
- SysActs.prototype.SetMinimumFramerate = function (f)
- {
- if (f < 1)
- f = 1;
- if (f > 120)
- f = 120;
- this.runtime.minimumFramerate = f;
- };
- function SortZOrderList(a, b)
- {
- var layerA = a[0];
- var layerB = b[0];
- var diff = layerA - layerB;
- if (diff !== 0)
- return diff;
- var indexA = a[1];
- var indexB = b[1];
- return indexA - indexB;
- };
- function SortInstancesByValue(a, b)
- {
- return a[1] - b[1];
- };
- SysActs.prototype.SortZOrderByInstVar = function (obj, iv)
- {
- if (!obj)
- return;
- var i, len, inst, value, r, layer, toZ;
- var sol = obj.getCurrentSol();
- var pickedInstances = sol.getObjects();
- var zOrderList = [];
- var instValues = [];
- var layout = this.runtime.running_layout;
- var isFamily = obj.is_family;
- var familyIndex = obj.family_index;
- for (i = 0, len = pickedInstances.length; i < len; ++i)
- {
- inst = pickedInstances[i];
- if (!inst.layer)
- continue; // not a world instance
- if (isFamily)
- value = inst.instance_vars[iv + inst.type.family_var_map[familyIndex]];
- else
- value = inst.instance_vars[iv];
- zOrderList.push([
- inst.layer.index,
- inst.get_zindex()
- ]);
- instValues.push([
- inst,
- value
- ]);
- }
- if (!zOrderList.length)
- return; // no instances were world instances
- zOrderList.sort(SortZOrderList);
- instValues.sort(SortInstancesByValue);
- for (i = 0, len = zOrderList.length; i < len; ++i)
- {
- inst = instValues[i][0]; // instance in the order we want
- layer = layout.layers[zOrderList[i][0]]; // layer to put it on
- toZ = zOrderList[i][1]; // Z index on that layer to put it
- if (layer.instances[toZ] !== inst) // not already got this instance there
- {
- layer.instances[toZ] = inst; // update instance
- inst.layer = layer; // update instance's layer reference (could have changed)
- layer.setZIndicesStaleFrom(toZ); // mark Z indices stale from this point since they have changed
- }
- }
- };
- sysProto.acts = new SysActs();
- function SysExps() {};
- SysExps.prototype["int"] = function(ret, x)
- {
- if (cr.is_string(x))
- {
- ret.set_int(parseInt(x, 10));
- if (isNaN(ret.data))
- ret.data = 0;
- }
- else
- ret.set_int(x);
- };
- SysExps.prototype["float"] = function(ret, x)
- {
- if (cr.is_string(x))
- {
- ret.set_float(parseFloat(x));
- if (isNaN(ret.data))
- ret.data = 0;
- }
- else
- ret.set_float(x);
- };
- SysExps.prototype.str = function(ret, x)
- {
- if (cr.is_string(x))
- ret.set_string(x);
- else
- ret.set_string(x.toString());
- };
- SysExps.prototype.len = function(ret, x)
- {
- ret.set_int(x.length || 0);
- };
- SysExps.prototype.random = function (ret, a, b)
- {
- if (b === undefined)
- {
- ret.set_float(Math.random() * a);
- }
- else
- {
- ret.set_float(Math.random() * (b - a) + a);
- }
- };
- SysExps.prototype.sqrt = function(ret, x)
- {
- ret.set_float(Math.sqrt(x));
- };
- SysExps.prototype.abs = function(ret, x)
- {
- ret.set_float(Math.abs(x));
- };
- SysExps.prototype.round = function(ret, x)
- {
- ret.set_int(Math.round(x));
- };
- SysExps.prototype.floor = function(ret, x)
- {
- ret.set_int(Math.floor(x));
- };
- SysExps.prototype.ceil = function(ret, x)
- {
- ret.set_int(Math.ceil(x));
- };
- SysExps.prototype.sin = function(ret, x)
- {
- ret.set_float(Math.sin(cr.to_radians(x)));
- };
- SysExps.prototype.cos = function(ret, x)
- {
- ret.set_float(Math.cos(cr.to_radians(x)));
- };
- SysExps.prototype.tan = function(ret, x)
- {
- ret.set_float(Math.tan(cr.to_radians(x)));
- };
- SysExps.prototype.asin = function(ret, x)
- {
- ret.set_float(cr.to_degrees(Math.asin(x)));
- };
- SysExps.prototype.acos = function(ret, x)
- {
- ret.set_float(cr.to_degrees(Math.acos(x)));
- };
- SysExps.prototype.atan = function(ret, x)
- {
- ret.set_float(cr.to_degrees(Math.atan(x)));
- };
- SysExps.prototype.exp = function(ret, x)
- {
- ret.set_float(Math.exp(x));
- };
- SysExps.prototype.ln = function(ret, x)
- {
- ret.set_float(Math.log(x));
- };
- SysExps.prototype.log10 = function(ret, x)
- {
- ret.set_float(Math.log(x) / Math.LN10);
- };
- SysExps.prototype.max = function(ret)
- {
- var max_ = arguments[1];
- if (typeof max_ !== "number")
- max_ = 0;
- var i, len, a;
- for (i = 2, len = arguments.length; i < len; i++)
- {
- a = arguments[i];
- if (typeof a !== "number")
- continue; // ignore non-numeric types
- if (max_ < a)
- max_ = a;
- }
- ret.set_float(max_);
- };
- SysExps.prototype.min = function(ret)
- {
- var min_ = arguments[1];
- if (typeof min_ !== "number")
- min_ = 0;
- var i, len, a;
- for (i = 2, len = arguments.length; i < len; i++)
- {
- a = arguments[i];
- if (typeof a !== "number")
- continue; // ignore non-numeric types
- if (min_ > a)
- min_ = a;
- }
- ret.set_float(min_);
- };
- SysExps.prototype.dt = function(ret)
- {
- ret.set_float(this.runtime.dt);
- };
- SysExps.prototype.timescale = function(ret)
- {
- ret.set_float(this.runtime.timescale);
- };
- SysExps.prototype.wallclocktime = function(ret)
- {
- ret.set_float((Date.now() - this.runtime.start_time) / 1000.0);
- };
- SysExps.prototype.time = function(ret)
- {
- ret.set_float(this.runtime.kahanTime.sum);
- };
- SysExps.prototype.tickcount = function(ret)
- {
- ret.set_int(this.runtime.tickcount);
- };
- SysExps.prototype.objectcount = function(ret)
- {
- ret.set_int(this.runtime.objectcount);
- };
- SysExps.prototype.fps = function(ret)
- {
- ret.set_int(this.runtime.fps);
- };
- SysExps.prototype.loopindex = function(ret, name_)
- {
- var loop, i, len;
- if (!this.runtime.loop_stack.length)
- {
- ret.set_int(0);
- return;
- }
- if (name_)
- {
- for (i = this.runtime.loop_stack_index; i >= 0; --i)
- {
- loop = this.runtime.loop_stack[i];
- if (loop.name === name_)
- {
- ret.set_int(loop.index);
- return;
- }
- }
- ret.set_int(0);
- }
- else
- {
- loop = this.runtime.getCurrentLoop();
- ret.set_int(loop ? loop.index : -1);
- }
- };
- SysExps.prototype.distance = function(ret, x1, y1, x2, y2)
- {
- ret.set_float(cr.distanceTo(x1, y1, x2, y2));
- };
- SysExps.prototype.angle = function(ret, x1, y1, x2, y2)
- {
- ret.set_float(cr.to_degrees(cr.angleTo(x1, y1, x2, y2)));
- };
- SysExps.prototype.scrollx = function(ret)
- {
- ret.set_float(this.runtime.running_layout.scrollX);
- };
- SysExps.prototype.scrolly = function(ret)
- {
- ret.set_float(this.runtime.running_layout.scrollY);
- };
- SysExps.prototype.newline = function(ret)
- {
- ret.set_string("\n");
- };
- SysExps.prototype.lerp = function(ret, a, b, x)
- {
- ret.set_float(cr.lerp(a, b, x));
- };
- SysExps.prototype.qarp = function(ret, a, b, c, x)
- {
- ret.set_float(cr.qarp(a, b, c, x));
- };
- SysExps.prototype.cubic = function(ret, a, b, c, d, x)
- {
- ret.set_float(cr.cubic(a, b, c, d, x));
- };
- SysExps.prototype.cosp = function(ret, a, b, x)
- {
- ret.set_float(cr.cosp(a, b, x));
- };
- SysExps.prototype.windowwidth = function(ret)
- {
- ret.set_int(this.runtime.width);
- };
- SysExps.prototype.windowheight = function(ret)
- {
- ret.set_int(this.runtime.height);
- };
- SysExps.prototype.uppercase = function(ret, str)
- {
- ret.set_string(cr.is_string(str) ? str.toUpperCase() : "");
- };
- SysExps.prototype.lowercase = function(ret, str)
- {
- ret.set_string(cr.is_string(str) ? str.toLowerCase() : "");
- };
- SysExps.prototype.clamp = function(ret, x, l, u)
- {
- if (x < l)
- ret.set_float(l);
- else if (x > u)
- ret.set_float(u);
- else
- ret.set_float(x);
- };
- SysExps.prototype.layerscale = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(layer.scale);
- };
- SysExps.prototype.layeropacity = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(layer.opacity * 100);
- };
- SysExps.prototype.layerscalerate = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(layer.zoomRate);
- };
- SysExps.prototype.layerparallaxx = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(layer.parallaxX * 100);
- };
- SysExps.prototype.layerparallaxy = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(layer.parallaxY * 100);
- };
- SysExps.prototype.layerindex = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_int(-1);
- else
- ret.set_int(layer.index);
- };
- SysExps.prototype.layoutscale = function (ret)
- {
- if (this.runtime.running_layout)
- ret.set_float(this.runtime.running_layout.scale);
- else
- ret.set_float(0);
- };
- SysExps.prototype.layoutangle = function (ret)
- {
- ret.set_float(cr.to_degrees(this.runtime.running_layout.angle));
- };
- SysExps.prototype.layerangle = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- if (!layer)
- ret.set_float(0);
- else
- ret.set_float(cr.to_degrees(layer.angle));
- };
- SysExps.prototype.layoutwidth = function (ret)
- {
- ret.set_int(this.runtime.running_layout.width);
- };
- SysExps.prototype.layoutheight = function (ret)
- {
- ret.set_int(this.runtime.running_layout.height);
- };
- SysExps.prototype.find = function (ret, text, searchstr)
- {
- if (cr.is_string(text) && cr.is_string(searchstr))
- ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "i")));
- else
- ret.set_int(-1);
- };
- SysExps.prototype.findcase = function (ret, text, searchstr)
- {
- if (cr.is_string(text) && cr.is_string(searchstr))
- ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "")));
- else
- ret.set_int(-1);
- };
- SysExps.prototype.left = function (ret, text, n)
- {
- ret.set_string(cr.is_string(text) ? text.substr(0, n) : "");
- };
- SysExps.prototype.right = function (ret, text, n)
- {
- ret.set_string(cr.is_string(text) ? text.substr(text.length - n) : "");
- };
- SysExps.prototype.mid = function (ret, text, index_, length_)
- {
- ret.set_string(cr.is_string(text) ? text.substr(index_, length_) : "");
- };
- SysExps.prototype.tokenat = function (ret, text, index_, sep)
- {
- if (cr.is_string(text) && cr.is_string(sep))
- {
- var arr = text.split(sep);
- var i = cr.floor(index_);
- if (i < 0 || i >= arr.length)
- ret.set_string("");
- else
- ret.set_string(arr[i]);
- }
- else
- ret.set_string("");
- };
- SysExps.prototype.tokencount = function (ret, text, sep)
- {
- if (cr.is_string(text) && text.length)
- ret.set_int(text.split(sep).length);
- else
- ret.set_int(0);
- };
- SysExps.prototype.replace = function (ret, text, find_, replace_)
- {
- if (cr.is_string(text) && cr.is_string(find_) && cr.is_string(replace_))
- ret.set_string(text.replace(new RegExp(cr.regexp_escape(find_), "gi"), replace_));
- else
- ret.set_string(cr.is_string(text) ? text : "");
- };
- SysExps.prototype.trim = function (ret, text)
- {
- ret.set_string(cr.is_string(text) ? text.trim() : "");
- };
- SysExps.prototype.pi = function (ret)
- {
- ret.set_float(cr.PI);
- };
- SysExps.prototype.layoutname = function (ret)
- {
- if (this.runtime.running_layout)
- ret.set_string(this.runtime.running_layout.name);
- else
- ret.set_string("");
- };
- SysExps.prototype.renderer = function (ret)
- {
- ret.set_string(this.runtime.gl ? "webgl" : "canvas2d");
- };
- SysExps.prototype.rendererdetail = function (ret)
- {
- ret.set_string(this.runtime.glUnmaskedRenderer);
- };
- SysExps.prototype.anglediff = function (ret, a, b)
- {
- ret.set_float(cr.to_degrees(cr.angleDiff(cr.to_radians(a), cr.to_radians(b))));
- };
- SysExps.prototype.choose = function (ret)
- {
- var index = cr.floor(Math.random() * (arguments.length - 1));
- ret.set_any(arguments[index + 1]);
- };
- SysExps.prototype.rgb = function (ret, r, g, b)
- {
- ret.set_int(cr.RGB(r, g, b));
- };
- SysExps.prototype.projectversion = function (ret)
- {
- ret.set_string(this.runtime.versionstr);
- };
- SysExps.prototype.projectname = function (ret)
- {
- ret.set_string(this.runtime.projectName);
- };
- SysExps.prototype.anglelerp = function (ret, a, b, x)
- {
- a = cr.to_radians(a);
- b = cr.to_radians(b);
- var diff = cr.angleDiff(a, b);
- if (cr.angleClockwise(b, a))
- {
- ret.set_float(cr.to_clamped_degrees(a + diff * x));
- }
- else
- {
- ret.set_float(cr.to_clamped_degrees(a - diff * x));
- }
- };
- SysExps.prototype.anglerotate = function (ret, a, b, c)
- {
- a = cr.to_radians(a);
- b = cr.to_radians(b);
- c = cr.to_radians(c);
- ret.set_float(cr.to_clamped_degrees(cr.angleRotate(a, b, c)));
- };
- SysExps.prototype.zeropad = function (ret, n, d)
- {
- var s = (n < 0 ? "-" : "");
- if (n < 0) n = -n;
- var zeroes = d - n.toString().length;
- for (var i = 0; i < zeroes; i++)
- s += "0";
- ret.set_string(s + n.toString());
- };
- SysExps.prototype.cpuutilisation = function (ret)
- {
- ret.set_float(this.runtime.cpuutilisation / 1000);
- };
- SysExps.prototype.viewportleft = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.viewLeft : 0);
- };
- SysExps.prototype.viewporttop = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.viewTop : 0);
- };
- SysExps.prototype.viewportright = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.viewRight : 0);
- };
- SysExps.prototype.viewportbottom = function (ret, layerparam)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.viewBottom : 0);
- };
- SysExps.prototype.loadingprogress = function (ret)
- {
- ret.set_float(this.runtime.loadingprogress);
- };
- SysExps.prototype.unlerp = function(ret, a, b, y)
- {
- ret.set_float(cr.unlerp(a, b, y));
- };
- SysExps.prototype.canvassnapshot = function (ret)
- {
- ret.set_string(this.runtime.snapshotData);
- };
- SysExps.prototype.urlencode = function (ret, s)
- {
- ret.set_string(encodeURIComponent(s));
- };
- SysExps.prototype.urldecode = function (ret, s)
- {
- ret.set_string(decodeURIComponent(s));
- };
- SysExps.prototype.canvastolayerx = function (ret, layerparam, x, y)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.canvasToLayer(x, y, true) : 0);
- };
- SysExps.prototype.canvastolayery = function (ret, layerparam, x, y)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.canvasToLayer(x, y, false) : 0);
- };
- SysExps.prototype.layertocanvasx = function (ret, layerparam, x, y)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.layerToCanvas(x, y, true) : 0);
- };
- SysExps.prototype.layertocanvasy = function (ret, layerparam, x, y)
- {
- var layer = this.runtime.getLayer(layerparam);
- ret.set_float(layer ? layer.layerToCanvas(x, y, false) : 0);
- };
- SysExps.prototype.savestatejson = function (ret)
- {
- ret.set_string(this.runtime.lastSaveJson);
- };
- SysExps.prototype.imagememoryusage = function (ret)
- {
- if (this.runtime.glwrap)
- ret.set_float(Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100);
- else
- ret.set_float(0);
- };
- SysExps.prototype.regexsearch = function (ret, str_, regex_, flags_)
- {
- var regex = getRegex(regex_, flags_);
- ret.set_int(str_ ? str_.search(regex) : -1);
- };
- SysExps.prototype.regexreplace = function (ret, str_, regex_, flags_, replace_)
- {
- var regex = getRegex(regex_, flags_);
- ret.set_string(str_ ? str_.replace(regex, replace_) : "");
- };
- var regexMatches = [];
- var lastMatchesStr = "";
- var lastMatchesRegex = "";
- var lastMatchesFlags = "";
- function updateRegexMatches(str_, regex_, flags_)
- {
- if (str_ === lastMatchesStr && regex_ === lastMatchesRegex && flags_ === lastMatchesFlags)
- return;
- var regex = getRegex(regex_, flags_);
- regexMatches = str_.match(regex);
- lastMatchesStr = str_;
- lastMatchesRegex = regex_;
- lastMatchesFlags = flags_;
- };
- SysExps.prototype.regexmatchcount = function (ret, str_, regex_, flags_)
- {
- var regex = getRegex(regex_, flags_);
- updateRegexMatches(str_.toString(), regex_, flags_);
- ret.set_int(regexMatches ? regexMatches.length : 0);
- };
- SysExps.prototype.regexmatchat = function (ret, str_, regex_, flags_, index_)
- {
- index_ = Math.floor(index_);
- var regex = getRegex(regex_, flags_);
- updateRegexMatches(str_.toString(), regex_, flags_);
- if (!regexMatches || index_ < 0 || index_ >= regexMatches.length)
- ret.set_string("");
- else
- ret.set_string(regexMatches[index_]);
- };
- SysExps.prototype.infinity = function (ret)
- {
- ret.set_float(Infinity);
- };
- SysExps.prototype.setbit = function (ret, n, b, v)
- {
- n = n | 0;
- b = b | 0;
- v = (v !== 0 ? 1 : 0);
- ret.set_int((n & ~(1 << b)) | (v << b));
- };
- SysExps.prototype.togglebit = function (ret, n, b)
- {
- n = n | 0;
- b = b | 0;
- ret.set_int(n ^ (1 << b));
- };
- SysExps.prototype.getbit = function (ret, n, b)
- {
- n = n | 0;
- b = b | 0;
- ret.set_int((n & (1 << b)) ? 1 : 0);
- };
- SysExps.prototype.originalwindowwidth = function (ret)
- {
- ret.set_int(this.runtime.original_width);
- };
- SysExps.prototype.originalwindowheight = function (ret)
- {
- ret.set_int(this.runtime.original_height);
- };
- sysProto.exps = new SysExps();
- sysProto.runWaits = function ()
- {
- var i, j, len, w, k, s, ss;
- var evinfo = this.runtime.getCurrentEventStack();
- for (i = 0, len = this.waits.length; i < len; i++)
- {
- w = this.waits[i];
- if (w.time === -1) // signalled wait
- {
- if (!w.signalled)
- continue; // not yet signalled
- }
- else // timer wait
- {
- if (w.time > this.runtime.kahanTime.sum)
- continue; // timer not yet expired
- }
- evinfo.current_event = w.ev;
- evinfo.actindex = w.actindex;
- evinfo.cndindex = 0;
- for (k in w.sols)
- {
- if (w.sols.hasOwnProperty(k))
- {
- s = this.runtime.types_by_index[parseInt(k, 10)].getCurrentSol();
- ss = w.sols[k];
- s.select_all = ss.sa;
- cr.shallowAssignArray(s.instances, ss.insts);
- freeSolStateObject(ss);
- }
- }
- w.ev.resume_actions_and_subevents();
- this.runtime.clearSol(w.solModifiers);
- w.deleteme = true;
- }
- for (i = 0, j = 0, len = this.waits.length; i < len; i++)
- {
- w = this.waits[i];
- this.waits[j] = w;
- if (w.deleteme)
- freeWaitObject(w);
- else
- j++;
- }
- cr.truncateArray(this.waits, j);
- };
-}());
-;
-(function () {
- cr.add_common_aces = function (m, pluginProto)
- {
- var singleglobal_ = m[1];
- var position_aces = m[3];
- var size_aces = m[4];
- var angle_aces = m[5];
- var appearance_aces = m[6];
- var zorder_aces = m[7];
- var effects_aces = m[8];
- if (!pluginProto.cnds)
- pluginProto.cnds = {};
- if (!pluginProto.acts)
- pluginProto.acts = {};
- if (!pluginProto.exps)
- pluginProto.exps = {};
- var cnds = pluginProto.cnds;
- var acts = pluginProto.acts;
- var exps = pluginProto.exps;
- if (position_aces)
- {
- cnds.CompareX = function (cmp, x)
- {
- return cr.do_cmp(this.x, cmp, x);
- };
- cnds.CompareY = function (cmp, y)
- {
- return cr.do_cmp(this.y, cmp, y);
- };
- cnds.IsOnScreen = function ()
- {
- var layer = this.layer;
- this.update_bbox();
- var bbox = this.bbox;
- return !(bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom);
- };
- cnds.IsOutsideLayout = function ()
- {
- this.update_bbox();
- var bbox = this.bbox;
- var layout = this.runtime.running_layout;
- return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height);
- };
- cnds.PickDistance = function (which, x, y)
- {
- var sol = this.getCurrentSol();
- var instances = sol.getObjects();
- if (!instances.length)
- return false;
- var inst = instances[0];
- var pickme = inst;
- var dist = cr.distanceTo(inst.x, inst.y, x, y);
- var i, len, d;
- for (i = 1, len = instances.length; i < len; i++)
- {
- inst = instances[i];
- d = cr.distanceTo(inst.x, inst.y, x, y);
- if ((which === 0 && d < dist) || (which === 1 && d > dist))
- {
- dist = d;
- pickme = inst;
- }
- }
- sol.pick_one(pickme);
- return true;
- };
- acts.SetX = function (x)
- {
- if (this.x !== x)
- {
- this.x = x;
- this.set_bbox_changed();
- }
- };
- acts.SetY = function (y)
- {
- if (this.y !== y)
- {
- this.y = y;
- this.set_bbox_changed();
- }
- };
- acts.SetPos = function (x, y)
- {
- if (this.x !== x || this.y !== y)
- {
- this.x = x;
- this.y = y;
- this.set_bbox_changed();
- }
- };
- acts.SetPosToObject = function (obj, imgpt)
- {
- var inst = obj.getPairedInstance(this);
- if (!inst)
- return;
- var newx, newy;
- if (inst.getImagePoint)
- {
- newx = inst.getImagePoint(imgpt, true);
- newy = inst.getImagePoint(imgpt, false);
- }
- else
- {
- newx = inst.x;
- newy = inst.y;
- }
- if (this.x !== newx || this.y !== newy)
- {
- this.x = newx;
- this.y = newy;
- this.set_bbox_changed();
- }
- };
- acts.MoveForward = function (dist)
- {
- if (dist !== 0)
- {
- this.x += Math.cos(this.angle) * dist;
- this.y += Math.sin(this.angle) * dist;
- this.set_bbox_changed();
- }
- };
- acts.MoveAtAngle = function (a, dist)
- {
- if (dist !== 0)
- {
- this.x += Math.cos(cr.to_radians(a)) * dist;
- this.y += Math.sin(cr.to_radians(a)) * dist;
- this.set_bbox_changed();
- }
- };
- exps.X = function (ret)
- {
- ret.set_float(this.x);
- };
- exps.Y = function (ret)
- {
- ret.set_float(this.y);
- };
- exps.dt = function (ret)
- {
- ret.set_float(this.runtime.getDt(this));
- };
- }
- if (size_aces)
- {
- cnds.CompareWidth = function (cmp, w)
- {
- return cr.do_cmp(this.width, cmp, w);
- };
- cnds.CompareHeight = function (cmp, h)
- {
- return cr.do_cmp(this.height, cmp, h);
- };
- acts.SetWidth = function (w)
- {
- if (this.width !== w)
- {
- this.width = w;
- this.set_bbox_changed();
- }
- };
- acts.SetHeight = function (h)
- {
- if (this.height !== h)
- {
- this.height = h;
- this.set_bbox_changed();
- }
- };
- acts.SetSize = function (w, h)
- {
- if (this.width !== w || this.height !== h)
- {
- this.width = w;
- this.height = h;
- this.set_bbox_changed();
- }
- };
- exps.Width = function (ret)
- {
- ret.set_float(this.width);
- };
- exps.Height = function (ret)
- {
- ret.set_float(this.height);
- };
- exps.BBoxLeft = function (ret)
- {
- this.update_bbox();
- ret.set_float(this.bbox.left);
- };
- exps.BBoxTop = function (ret)
- {
- this.update_bbox();
- ret.set_float(this.bbox.top);
- };
- exps.BBoxRight = function (ret)
- {
- this.update_bbox();
- ret.set_float(this.bbox.right);
- };
- exps.BBoxBottom = function (ret)
- {
- this.update_bbox();
- ret.set_float(this.bbox.bottom);
- };
- }
- if (angle_aces)
- {
- cnds.AngleWithin = function (within, a)
- {
- return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within);
- };
- cnds.IsClockwiseFrom = function (a)
- {
- return cr.angleClockwise(this.angle, cr.to_radians(a));
- };
- cnds.IsBetweenAngles = function (a, b)
- {
- var lower = cr.to_clamped_radians(a);
- var upper = cr.to_clamped_radians(b);
- var angle = cr.clamp_angle(this.angle);
- var obtuse = (!cr.angleClockwise(upper, lower));
- if (obtuse)
- return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
- else
- return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
- };
- acts.SetAngle = function (a)
- {
- var newangle = cr.to_radians(cr.clamp_angle_degrees(a));
- if (isNaN(newangle))
- return;
- if (this.angle !== newangle)
- {
- this.angle = newangle;
- this.set_bbox_changed();
- }
- };
- acts.RotateClockwise = function (a)
- {
- if (a !== 0 && !isNaN(a))
- {
- this.angle += cr.to_radians(a);
- this.angle = cr.clamp_angle(this.angle);
- this.set_bbox_changed();
- }
- };
- acts.RotateCounterclockwise = function (a)
- {
- if (a !== 0 && !isNaN(a))
- {
- this.angle -= cr.to_radians(a);
- this.angle = cr.clamp_angle(this.angle);
- this.set_bbox_changed();
- }
- };
- acts.RotateTowardAngle = function (amt, target)
- {
- var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt));
- if (isNaN(newangle))
- return;
- if (this.angle !== newangle)
- {
- this.angle = newangle;
- this.set_bbox_changed();
- }
- };
- acts.RotateTowardPosition = function (amt, x, y)
- {
- var dx = x - this.x;
- var dy = y - this.y;
- var target = Math.atan2(dy, dx);
- var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt));
- if (isNaN(newangle))
- return;
- if (this.angle !== newangle)
- {
- this.angle = newangle;
- this.set_bbox_changed();
- }
- };
- acts.SetTowardPosition = function (x, y)
- {
- var dx = x - this.x;
- var dy = y - this.y;
- var newangle = Math.atan2(dy, dx);
- if (isNaN(newangle))
- return;
- if (this.angle !== newangle)
- {
- this.angle = newangle;
- this.set_bbox_changed();
- }
- };
- exps.Angle = function (ret)
- {
- ret.set_float(cr.to_clamped_degrees(this.angle));
- };
- }
- if (!singleglobal_)
- {
- cnds.CompareInstanceVar = function (iv, cmp, val)
- {
- return cr.do_cmp(this.instance_vars[iv], cmp, val);
- };
- cnds.IsBoolInstanceVarSet = function (iv)
- {
- return this.instance_vars[iv];
- };
- cnds.PickInstVarHiLow = function (which, iv)
- {
- var sol = this.getCurrentSol();
- var instances = sol.getObjects();
- if (!instances.length)
- return false;
- var inst = instances[0];
- var pickme = inst;
- var val = inst.instance_vars[iv];
- var i, len, v;
- for (i = 1, len = instances.length; i < len; i++)
- {
- inst = instances[i];
- v = inst.instance_vars[iv];
- if ((which === 0 && v < val) || (which === 1 && v > val))
- {
- val = v;
- pickme = inst;
- }
- }
- sol.pick_one(pickme);
- return true;
- };
- cnds.PickByUID = function (u)
- {
- var i, len, j, inst, families, instances, sol;
- var cnd = this.runtime.getCurrentCondition();
- if (cnd.inverted)
- {
- sol = this.getCurrentSol();
- if (sol.select_all)
- {
- sol.select_all = false;
- cr.clearArray(sol.instances);
- cr.clearArray(sol.else_instances);
- instances = this.instances;
- for (i = 0, len = instances.length; i < len; i++)
- {
- inst = instances[i];
- if (inst.uid === u)
- sol.else_instances.push(inst);
- else
- sol.instances.push(inst);
- }
- this.applySolToContainer();
- return !!sol.instances.length;
- }
- else
- {
- for (i = 0, j = 0, len = sol.instances.length; i < len; i++)
- {
- inst = sol.instances[i];
- sol.instances[j] = inst;
- if (inst.uid === u)
- {
- sol.else_instances.push(inst);
- }
- else
- j++;
- }
- cr.truncateArray(sol.instances, j);
- this.applySolToContainer();
- return !!sol.instances.length;
- }
- }
- else
- {
- inst = this.runtime.getObjectByUID(u);
- if (!inst)
- return false;
- sol = this.getCurrentSol();
- if (!sol.select_all && sol.instances.indexOf(inst) === -1)
- return false; // not picked
- if (this.is_family)
- {
- families = inst.type.families;
- for (i = 0, len = families.length; i < len; i++)
- {
- if (families[i] === this)
- {
- sol.pick_one(inst);
- this.applySolToContainer();
- return true;
- }
- }
- }
- else if (inst.type === this)
- {
- sol.pick_one(inst);
- this.applySolToContainer();
- return true;
- }
- return false;
- }
- };
- cnds.OnCreated = function ()
- {
- return true;
- };
- cnds.OnDestroyed = function ()
- {
- return true;
- };
- acts.SetInstanceVar = function (iv, val)
- {
- var myinstvars = this.instance_vars;
- if (cr.is_number(myinstvars[iv]))
- {
- if (cr.is_number(val))
- myinstvars[iv] = val;
- else
- myinstvars[iv] = parseFloat(val);
- }
- else if (cr.is_string(myinstvars[iv]))
- {
- if (cr.is_string(val))
- myinstvars[iv] = val;
- else
- myinstvars[iv] = val.toString();
- }
- else
-;
- };
- acts.AddInstanceVar = function (iv, val)
- {
- var myinstvars = this.instance_vars;
- if (cr.is_number(myinstvars[iv]))
- {
- if (cr.is_number(val))
- myinstvars[iv] += val;
- else
- myinstvars[iv] += parseFloat(val);
- }
- else if (cr.is_string(myinstvars[iv]))
- {
- if (cr.is_string(val))
- myinstvars[iv] += val;
- else
- myinstvars[iv] += val.toString();
- }
- else
-;
- };
- acts.SubInstanceVar = function (iv, val)
- {
- var myinstvars = this.instance_vars;
- if (cr.is_number(myinstvars[iv]))
- {
- if (cr.is_number(val))
- myinstvars[iv] -= val;
- else
- myinstvars[iv] -= parseFloat(val);
- }
- else
-;
- };
- acts.SetBoolInstanceVar = function (iv, val)
- {
- this.instance_vars[iv] = val ? 1 : 0;
- };
- acts.ToggleBoolInstanceVar = function (iv)
- {
- this.instance_vars[iv] = 1 - this.instance_vars[iv];
- };
- acts.Destroy = function ()
- {
- this.runtime.DestroyInstance(this);
- };
- if (!acts.LoadFromJsonString)
- {
- acts.LoadFromJsonString = function (str_)
- {
- var o, i, len, binst;
- try {
- o = JSON.parse(str_);
- }
- catch (e) {
- return;
- }
- this.runtime.loadInstanceFromJSON(this, o, true);
- if (this.afterLoad)
- this.afterLoad();
- if (this.behavior_insts)
- {
- for (i = 0, len = this.behavior_insts.length; i < len; ++i)
- {
- binst = this.behavior_insts[i];
- if (binst.afterLoad)
- binst.afterLoad();
- }
- }
- };
- }
- exps.Count = function (ret)
- {
- var count = ret.object_class.instances.length;
- var i, len, inst;
- for (i = 0, len = this.runtime.createRow.length; i < len; i++)
- {
- inst = this.runtime.createRow[i];
- if (ret.object_class.is_family)
- {
- if (inst.type.families.indexOf(ret.object_class) >= 0)
- count++;
- }
- else
- {
- if (inst.type === ret.object_class)
- count++;
- }
- }
- ret.set_int(count);
- };
- exps.PickedCount = function (ret)
- {
- ret.set_int(ret.object_class.getCurrentSol().getObjects().length);
- };
- exps.UID = function (ret)
- {
- ret.set_int(this.uid);
- };
- exps.IID = function (ret)
- {
- ret.set_int(this.get_iid());
- };
- if (!exps.AsJSON)
- {
- exps.AsJSON = function (ret)
- {
- ret.set_string(JSON.stringify(this.runtime.saveInstanceToJSON(this, true)));
- };
- }
- }
- if (appearance_aces)
- {
- cnds.IsVisible = function ()
- {
- return this.visible;
- };
- acts.SetVisible = function (v)
- {
- if (!v !== !this.visible)
- {
- this.visible = !!v;
- this.runtime.redraw = true;
- }
- };
- cnds.CompareOpacity = function (cmp, x)
- {
- return cr.do_cmp(cr.round6dp(this.opacity * 100), cmp, x);
- };
- acts.SetOpacity = function (x)
- {
- var new_opacity = x / 100.0;
- if (new_opacity < 0)
- new_opacity = 0;
- else if (new_opacity > 1)
- new_opacity = 1;
- if (new_opacity !== this.opacity)
- {
- this.opacity = new_opacity;
- this.runtime.redraw = true;
- }
- };
- exps.Opacity = function (ret)
- {
- ret.set_float(cr.round6dp(this.opacity * 100.0));
- };
- }
- if (zorder_aces)
- {
- cnds.IsOnLayer = function (layer_)
- {
- if (!layer_)
- return false;
- return this.layer === layer_;
- };
- cnds.PickTopBottom = function (which_)
- {
- var sol = this.getCurrentSol();
- var instances = sol.getObjects();
- if (!instances.length)
- return false;
- var inst = instances[0];
- var pickme = inst;
- var i, len;
- for (i = 1, len = instances.length; i < len; i++)
- {
- inst = instances[i];
- if (which_ === 0)
- {
- if (inst.layer.index > pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() > pickme.get_zindex()))
- {
- pickme = inst;
- }
- }
- else
- {
- if (inst.layer.index < pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() < pickme.get_zindex()))
- {
- pickme = inst;
- }
- }
- }
- sol.pick_one(pickme);
- return true;
- };
- acts.MoveToTop = function ()
- {
- var layer = this.layer;
- var layer_instances = layer.instances;
- if (layer_instances.length && layer_instances[layer_instances.length - 1] === this)
- return; // is already at top
- layer.removeFromInstanceList(this, false);
- layer.appendToInstanceList(this, false);
- this.runtime.redraw = true;
- };
- acts.MoveToBottom = function ()
- {
- var layer = this.layer;
- var layer_instances = layer.instances;
- if (layer_instances.length && layer_instances[0] === this)
- return; // is already at bottom
- layer.removeFromInstanceList(this, false);
- layer.prependToInstanceList(this, false);
- this.runtime.redraw = true;
- };
- acts.MoveToLayer = function (layerMove)
- {
- if (!layerMove || layerMove == this.layer)
- return;
- this.layer.removeFromInstanceList(this, true);
- this.layer = layerMove;
- layerMove.appendToInstanceList(this, true);
- this.runtime.redraw = true;
- };
- acts.ZMoveToObject = function (where_, obj_)
- {
- var isafter = (where_ === 0);
- if (!obj_)
- return;
- var other = obj_.getFirstPicked(this);
- if (!other || other.uid === this.uid)
- return;
- if (this.layer.index !== other.layer.index)
- {
- this.layer.removeFromInstanceList(this, true);
- this.layer = other.layer;
- other.layer.appendToInstanceList(this, true);
- }
- this.layer.moveInstanceAdjacent(this, other, isafter);
- this.runtime.redraw = true;
- };
- exps.LayerNumber = function (ret)
- {
- ret.set_int(this.layer.number);
- };
- exps.LayerName = function (ret)
- {
- ret.set_string(this.layer.name);
- };
- exps.ZIndex = function (ret)
- {
- ret.set_int(this.get_zindex());
- };
- }
- if (effects_aces)
- {
- acts.SetEffectEnabled = function (enable_, effectname_)
- {
- if (!this.runtime.glwrap)
- return;
- var i = this.type.getEffectIndexByName(effectname_);
- if (i < 0)
- return; // effect name not found
- var enable = (enable_ === 1);
- if (this.active_effect_flags[i] === enable)
- return; // no change
- this.active_effect_flags[i] = enable;
- this.updateActiveEffects();
- this.runtime.redraw = true;
- };
- acts.SetEffectParam = function (effectname_, index_, value_)
- {
- if (!this.runtime.glwrap)
- return;
- var i = this.type.getEffectIndexByName(effectname_);
- if (i < 0)
- return; // effect name not found
- var et = this.type.effect_types[i];
- var params = this.effect_params[i];
- index_ = Math.floor(index_);
- if (index_ < 0 || index_ >= params.length)
- return; // effect index out of bounds
- if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
- value_ /= 100.0;
- if (params[index_] === value_)
- return; // no change
- params[index_] = value_;
- if (et.active)
- this.runtime.redraw = true;
- };
- }
- };
- cr.set_bbox_changed = function ()
- {
- this.bbox_changed = true; // will recreate next time box requested
- this.cell_changed = true;
- this.type.any_cell_changed = true; // avoid unnecessary updateAllBBox() calls
- this.runtime.redraw = true; // assume runtime needs to redraw
- var i, len, callbacks = this.bbox_changed_callbacks;
- for (i = 0, len = callbacks.length; i < len; ++i)
- {
- callbacks[i](this);
- }
- if (this.layer.useRenderCells)
- this.update_bbox();
- };
- cr.add_bbox_changed_callback = function (f)
- {
- if (f)
- {
- this.bbox_changed_callbacks.push(f);
- }
- };
- cr.update_bbox = function ()
- {
- if (!this.bbox_changed)
- return; // bounding box not changed
- var bbox = this.bbox;
- var bquad = this.bquad;
- bbox.set(this.x, this.y, this.x + this.width, this.y + this.height);
- bbox.offset(-this.hotspotX * this.width, -this.hotspotY * this.height);
- if (!this.angle)
- {
- bquad.set_from_rect(bbox); // make bounding quad from box
- }
- else
- {
- bbox.offset(-this.x, -this.y); // translate to origin
- bquad.set_from_rotated_rect(bbox, this.angle); // rotate around origin
- bquad.offset(this.x, this.y); // translate back to original position
- bquad.bounding_box(bbox);
- }
- bbox.normalize();
- this.bbox_changed = false; // bounding box up to date
- this.update_render_cell();
- };
- var tmprc = new cr.rect(0, 0, 0, 0);
- cr.update_render_cell = function ()
- {
- if (!this.layer.useRenderCells)
- return;
- var mygrid = this.layer.render_grid;
- var bbox = this.bbox;
- tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
- if (this.rendercells.equals(tmprc))
- return;
- if (this.rendercells.right < this.rendercells.left)
- mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
- else
- mygrid.update(this, this.rendercells, tmprc);
- this.rendercells.copy(tmprc);
- this.layer.render_list_stale = true;
- };
- cr.update_collision_cell = function ()
- {
- if (!this.cell_changed || !this.collisionsEnabled)
- return;
- this.update_bbox();
- var mygrid = this.type.collision_grid;
- var bbox = this.bbox;
- tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
- if (this.collcells.equals(tmprc))
- return;
- if (this.collcells.right < this.collcells.left)
- mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
- else
- mygrid.update(this, this.collcells, tmprc);
- this.collcells.copy(tmprc);
- this.cell_changed = false;
- };
- cr.inst_contains_pt = function (x, y)
- {
- if (!this.bbox.contains_pt(x, y))
- return false;
- if (!this.bquad.contains_pt(x, y))
- return false;
- if (this.tilemap_exists)
- return this.testPointOverlapTile(x, y);
- if (this.collision_poly && !this.collision_poly.is_empty())
- {
- this.collision_poly.cache_poly(this.width, this.height, this.angle);
- return this.collision_poly.contains_pt(x - this.x, y - this.y);
- }
- else
- return true;
- };
- cr.inst_get_iid = function ()
- {
- this.type.updateIIDs();
- return this.iid;
- };
- cr.inst_get_zindex = function ()
- {
- this.layer.updateZIndices();
- return this.zindex;
- };
- cr.inst_updateActiveEffects = function ()
- {
- cr.clearArray(this.active_effect_types);
- var i, len, et;
- var preserves_opaqueness = true;
- for (i = 0, len = this.active_effect_flags.length; i < len; i++)
- {
- if (this.active_effect_flags[i])
- {
- et = this.type.effect_types[i];
- this.active_effect_types.push(et);
- if (!et.preservesOpaqueness)
- preserves_opaqueness = false;
- }
- }
- this.uses_shaders = !!this.active_effect_types.length;
- this.shaders_preserve_opaqueness = preserves_opaqueness;
- };
- cr.inst_toString = function ()
- {
- return "Inst" + this.puid;
- };
- cr.type_getFirstPicked = function (frominst)
- {
- if (frominst && frominst.is_contained && frominst.type != this)
- {
- var i, len, s;
- for (i = 0, len = frominst.siblings.length; i < len; i++)
- {
- s = frominst.siblings[i];
- if (s.type == this)
- return s;
- }
- }
- var instances = this.getCurrentSol().getObjects();
- if (instances.length)
- return instances[0];
- else
- return null;
- };
- cr.type_getPairedInstance = function (inst)
- {
- var instances = this.getCurrentSol().getObjects();
- if (instances.length)
- return instances[inst.get_iid() % instances.length];
- else
- return null;
- };
- cr.type_updateIIDs = function ()
- {
- if (!this.stale_iids || this.is_family)
- return; // up to date or is family - don't want family to overwrite IIDs
- var i, len;
- for (i = 0, len = this.instances.length; i < len; i++)
- this.instances[i].iid = i;
- var next_iid = i;
- var createRow = this.runtime.createRow;
- for (i = 0, len = createRow.length; i < len; ++i)
- {
- if (createRow[i].type === this)
- createRow[i].iid = next_iid++;
- }
- this.stale_iids = false;
- };
- cr.type_getInstanceByIID = function (i)
- {
- if (i < this.instances.length)
- return this.instances[i];
- i -= this.instances.length;
- var createRow = this.runtime.createRow;
- var j, lenj;
- for (j = 0, lenj = createRow.length; j < lenj; ++j)
- {
- if (createRow[j].type === this)
- {
- if (i === 0)
- return createRow[j];
- --i;
- }
- }
-;
- return null;
- };
- cr.type_getCurrentSol = function ()
- {
- return this.solstack[this.cur_sol];
- };
- cr.type_pushCleanSol = function ()
- {
- this.cur_sol++;
- if (this.cur_sol === this.solstack.length)
- {
- this.solstack.push(new cr.selection(this));
- }
- else
- {
- this.solstack[this.cur_sol].select_all = true; // else clear next SOL
- cr.clearArray(this.solstack[this.cur_sol].else_instances);
- }
- };
- cr.type_pushCopySol = function ()
- {
- this.cur_sol++;
- if (this.cur_sol === this.solstack.length)
- this.solstack.push(new cr.selection(this));
- var clonesol = this.solstack[this.cur_sol];
- var prevsol = this.solstack[this.cur_sol - 1];
- if (prevsol.select_all)
- {
- clonesol.select_all = true;
- }
- else
- {
- clonesol.select_all = false;
- cr.shallowAssignArray(clonesol.instances, prevsol.instances);
- }
- cr.clearArray(clonesol.else_instances);
- };
- cr.type_popSol = function ()
- {
-;
- this.cur_sol--;
- };
- cr.type_getBehaviorByName = function (behname)
- {
- var i, len, j, lenj, f, index = 0;
- if (!this.is_family)
- {
- for (i = 0, len = this.families.length; i < len; i++)
- {
- f = this.families[i];
- for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
- {
- if (behname === f.behaviors[j].name)
- {
- this.extra["lastBehIndex"] = index;
- return f.behaviors[j];
- }
- index++;
- }
- }
- }
- for (i = 0, len = this.behaviors.length; i < len; i++) {
- if (behname === this.behaviors[i].name)
- {
- this.extra["lastBehIndex"] = index;
- return this.behaviors[i];
- }
- index++;
- }
- return null;
- };
- cr.type_getBehaviorIndexByName = function (behname)
- {
- var b = this.getBehaviorByName(behname);
- if (b)
- return this.extra["lastBehIndex"];
- else
- return -1;
- };
- cr.type_getEffectIndexByName = function (name_)
- {
- var i, len;
- for (i = 0, len = this.effect_types.length; i < len; i++)
- {
- if (this.effect_types[i].name === name_)
- return i;
- }
- return -1;
- };
- cr.type_applySolToContainer = function ()
- {
- if (!this.is_contained || this.is_family)
- return;
- var i, len, j, lenj, t, sol, sol2;
- this.updateIIDs();
- sol = this.getCurrentSol();
- var select_all = sol.select_all;
- var es = this.runtime.getCurrentEventStack();
- var orblock = es && es.current_event && es.current_event.orblock;
- for (i = 0, len = this.container.length; i < len; i++)
- {
- t = this.container[i];
- if (t === this)
- continue;
- t.updateIIDs();
- sol2 = t.getCurrentSol();
- sol2.select_all = select_all;
- if (!select_all)
- {
- cr.clearArray(sol2.instances);
- for (j = 0, lenj = sol.instances.length; j < lenj; ++j)
- sol2.instances[j] = t.getInstanceByIID(sol.instances[j].iid);
- if (orblock)
- {
- cr.clearArray(sol2.else_instances);
- for (j = 0, lenj = sol.else_instances.length; j < lenj; ++j)
- sol2.else_instances[j] = t.getInstanceByIID(sol.else_instances[j].iid);
- }
- }
- }
- };
- cr.type_toString = function ()
- {
- return "Type" + this.sid;
- };
- cr.do_cmp = function (x, cmp, y)
- {
- if (typeof x === "undefined" || typeof y === "undefined")
- return false;
- switch (cmp)
- {
- case 0: // equal
- return x === y;
- case 1: // not equal
- return x !== y;
- case 2: // less
- return x < y;
- case 3: // less/equal
- return x <= y;
- case 4: // greater
- return x > y;
- case 5: // greater/equal
- return x >= y;
- default:
-;
- return false;
- }
- };
-})();
-cr.shaders = {};
-;
-;
-cr.plugins_.Audio = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Audio.prototype;
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- };
- var audRuntime = null;
- var audInst = null;
- var audTag = "";
- var appPath = ""; // for Cordova only
- var API_HTML5 = 0;
- var API_WEBAUDIO = 1;
- var API_CORDOVA = 2;
- var API_APPMOBI = 3;
- var api = API_HTML5;
- var context = null;
- var audioBuffers = []; // cache of buffers
- var audioInstances = []; // cache of instances
- var lastAudio = null;
- var useOgg = false; // determined at create time
- var timescale_mode = 0;
- var silent = false;
- var masterVolume = 1;
- var listenerX = 0;
- var listenerY = 0;
- var isContextSuspended = false;
- var panningModel = 1; // HRTF
- var distanceModel = 1; // Inverse
- var refDistance = 10;
- var maxDistance = 10000;
- var rolloffFactor = 1;
- var micSource = null;
- var micTag = "";
- var useNextTouchWorkaround = false; // heuristic in case play() does not return a promise and we have to guess if the play was blocked
- var playOnNextInput = []; // C2AudioInstances with HTMLAudioElements to play on next input event
- var playMusicAsSoundWorkaround = false; // play music tracks with Web Audio API
- var hasPlayedDummyBuffer = false; // dummy buffer played to unblock AudioContext on some platforms
- function addAudioToPlayOnNextInput(a)
- {
- var i = playOnNextInput.indexOf(a);
- if (i === -1)
- playOnNextInput.push(a);
- };
- function tryPlayAudioElement(a)
- {
- var audioElem = a.instanceObject;
- var playRet;
- try {
- playRet = audioElem.play();
- }
- catch (err) {
- addAudioToPlayOnNextInput(a);
- return;
- }
- if (playRet) // promise was returned
- {
- playRet.catch(function (err)
- {
- addAudioToPlayOnNextInput(a);
- });
- }
- else if (useNextTouchWorkaround && !audRuntime.isInUserInputEvent)
- {
- addAudioToPlayOnNextInput(a);
- }
- };
- function playQueuedAudio()
- {
- var i, len, m, playRet;
- if (!hasPlayedDummyBuffer && !isContextSuspended && context)
- {
- playDummyBuffer();
- if (context["state"] === "running")
- hasPlayedDummyBuffer = true;
- }
- var tryPlay = playOnNextInput.slice(0);
- cr.clearArray(playOnNextInput);
- if (!silent)
- {
- for (i = 0, len = tryPlay.length; i < len; ++i)
- {
- m = tryPlay[i];
- if (!m.stopped && !m.is_paused)
- {
- playRet = m.instanceObject.play();
- if (playRet)
- {
- playRet.catch(function (err)
- {
- addAudioToPlayOnNextInput(m);
- });
- }
- }
- }
- }
- };
- function playDummyBuffer()
- {
- if (context["state"] === "suspended" && context["resume"])
- context["resume"]();
- if (!context["createBuffer"])
- return;
- var buffer = context["createBuffer"](1, 220, 22050);
- var source = context["createBufferSource"]();
- source["buffer"] = buffer;
- source["connect"](context["destination"]);
- startSource(source);
- };
- document.addEventListener("pointerup", playQueuedAudio, true);
- document.addEventListener("touchend", playQueuedAudio, true);
- document.addEventListener("click", playQueuedAudio, true);
- document.addEventListener("keydown", playQueuedAudio, true);
- document.addEventListener("gamepadconnected", playQueuedAudio, true);
- function dbToLinear(x)
- {
- var v = dbToLinear_nocap(x);
- if (!isFinite(v)) // accidentally passing a string can result in NaN; set volume to 0 if so
- v = 0;
- if (v < 0)
- v = 0;
- if (v > 1)
- v = 1;
- return v;
- };
- function linearToDb(x)
- {
- if (x < 0)
- x = 0;
- if (x > 1)
- x = 1;
- return linearToDb_nocap(x);
- };
- function dbToLinear_nocap(x)
- {
- return Math.pow(10, x / 20);
- };
- function linearToDb_nocap(x)
- {
- return (Math.log(x) / Math.log(10)) * 20;
- };
- var effects = {};
- function getDestinationForTag(tag)
- {
- tag = tag.toLowerCase();
- if (effects.hasOwnProperty(tag))
- {
- if (effects[tag].length)
- return effects[tag][0].getInputNode();
- }
- return context["destination"];
- };
- function createGain()
- {
- if (context["createGain"])
- return context["createGain"]();
- else
- return context["createGainNode"]();
- };
- function createDelay(d)
- {
- if (context["createDelay"])
- return context["createDelay"](d);
- else
- return context["createDelayNode"](d);
- };
- function startSource(s, scheduledTime)
- {
- if (s["start"])
- s["start"](scheduledTime || 0);
- else
- s["noteOn"](scheduledTime || 0);
- };
- function startSourceAt(s, x, d, scheduledTime)
- {
- if (s["start"])
- s["start"](scheduledTime || 0, x);
- else
- s["noteGrainOn"](scheduledTime || 0, x, d - x);
- };
- function stopSource(s)
- {
- try {
- if (s["stop"])
- s["stop"](0);
- else
- s["noteOff"](0);
- }
- catch (e) {}
- };
- function setAudioParam(ap, value, ramp, time)
- {
- if (!ap)
- return; // iOS is missing some parameters
- ap["cancelScheduledValues"](0);
- if (time === 0)
- {
- ap["value"] = value;
- return;
- }
- var curTime = context["currentTime"];
- time += curTime;
- switch (ramp) {
- case 0: // step
- ap["setValueAtTime"](value, time);
- break;
- case 1: // linear
- ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
- ap["linearRampToValueAtTime"](value, time);
- break;
- case 2: // exponential
- ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
- ap["exponentialRampToValueAtTime"](value, time);
- break;
- }
- };
- var filterTypes = ["lowpass", "highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass"];
- function FilterEffect(type, freq, detune, q, gain, mix)
- {
- this.type = "filter";
- this.params = [type, freq, detune, q, gain, mix];
- this.inputNode = createGain();
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix;
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - mix;
- this.filterNode = context["createBiquadFilter"]();
- if (typeof this.filterNode["type"] === "number")
- this.filterNode["type"] = type;
- else
- this.filterNode["type"] = filterTypes[type];
- this.filterNode["frequency"]["value"] = freq;
- if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
- this.filterNode["detune"]["value"] = detune;
- this.filterNode["Q"]["value"] = q;
- this.filterNode["gain"]["value"] = gain;
- this.inputNode["connect"](this.filterNode);
- this.inputNode["connect"](this.dryNode);
- this.filterNode["connect"](this.wetNode);
- };
- FilterEffect.prototype.connectTo = function (node)
- {
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- };
- FilterEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.filterNode["disconnect"]();
- this.wetNode["disconnect"]();
- this.dryNode["disconnect"]();
- };
- FilterEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- FilterEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[5] = value;
- setAudioParam(this.wetNode["gain"], value, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
- break;
- case 1: // filter frequency
- this.params[1] = value;
- setAudioParam(this.filterNode["frequency"], value, ramp, time);
- break;
- case 2: // filter detune
- this.params[2] = value;
- setAudioParam(this.filterNode["detune"], value, ramp, time);
- break;
- case 3: // filter Q
- this.params[3] = value;
- setAudioParam(this.filterNode["Q"], value, ramp, time);
- break;
- case 4: // filter/delay gain (note value is in dB here)
- this.params[4] = value;
- setAudioParam(this.filterNode["gain"], value, ramp, time);
- break;
- }
- };
- function DelayEffect(delayTime, delayGain, mix)
- {
- this.type = "delay";
- this.params = [delayTime, delayGain, mix];
- this.inputNode = createGain();
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix;
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - mix;
- this.mainNode = createGain();
- this.delayNode = createDelay(delayTime);
- this.delayNode["delayTime"]["value"] = delayTime;
- this.delayGainNode = createGain();
- this.delayGainNode["gain"]["value"] = delayGain;
- this.inputNode["connect"](this.mainNode);
- this.inputNode["connect"](this.dryNode);
- this.mainNode["connect"](this.wetNode);
- this.mainNode["connect"](this.delayNode);
- this.delayNode["connect"](this.delayGainNode);
- this.delayGainNode["connect"](this.mainNode);
- };
- DelayEffect.prototype.connectTo = function (node)
- {
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- };
- DelayEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.mainNode["disconnect"]();
- this.delayNode["disconnect"]();
- this.delayGainNode["disconnect"]();
- this.wetNode["disconnect"]();
- this.dryNode["disconnect"]();
- };
- DelayEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- DelayEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[2] = value;
- setAudioParam(this.wetNode["gain"], value, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
- break;
- case 4: // filter/delay gain (note value is passed in dB but needs to be linear here)
- this.params[1] = dbToLinear(value);
- setAudioParam(this.delayGainNode["gain"], dbToLinear(value), ramp, time);
- break;
- case 5: // delay time
- this.params[0] = value;
- setAudioParam(this.delayNode["delayTime"], value, ramp, time);
- break;
- }
- };
- function ConvolveEffect(buffer, normalize, mix, src)
- {
- this.type = "convolve";
- this.params = [normalize, mix, src];
- this.inputNode = createGain();
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix;
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - mix;
- this.convolveNode = context["createConvolver"]();
- if (buffer)
- {
- this.convolveNode["normalize"] = normalize;
- this.convolveNode["buffer"] = buffer;
- }
- this.inputNode["connect"](this.convolveNode);
- this.inputNode["connect"](this.dryNode);
- this.convolveNode["connect"](this.wetNode);
- };
- ConvolveEffect.prototype.connectTo = function (node)
- {
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- };
- ConvolveEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.convolveNode["disconnect"]();
- this.wetNode["disconnect"]();
- this.dryNode["disconnect"]();
- };
- ConvolveEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- ConvolveEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[1] = value;
- setAudioParam(this.wetNode["gain"], value, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
- break;
- }
- };
- function FlangerEffect(delay, modulation, freq, feedback, mix)
- {
- this.type = "flanger";
- this.params = [delay, modulation, freq, feedback, mix];
- this.inputNode = createGain();
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - (mix / 2);
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix / 2;
- this.feedbackNode = createGain();
- this.feedbackNode["gain"]["value"] = feedback;
- this.delayNode = createDelay(delay + modulation);
- this.delayNode["delayTime"]["value"] = delay;
- this.oscNode = context["createOscillator"]();
- this.oscNode["frequency"]["value"] = freq;
- this.oscGainNode = createGain();
- this.oscGainNode["gain"]["value"] = modulation;
- this.inputNode["connect"](this.delayNode);
- this.inputNode["connect"](this.dryNode);
- this.delayNode["connect"](this.wetNode);
- this.delayNode["connect"](this.feedbackNode);
- this.feedbackNode["connect"](this.delayNode);
- this.oscNode["connect"](this.oscGainNode);
- this.oscGainNode["connect"](this.delayNode["delayTime"]);
- startSource(this.oscNode);
- };
- FlangerEffect.prototype.connectTo = function (node)
- {
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- };
- FlangerEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.delayNode["disconnect"]();
- this.oscNode["disconnect"]();
- this.oscGainNode["disconnect"]();
- this.dryNode["disconnect"]();
- this.wetNode["disconnect"]();
- this.feedbackNode["disconnect"]();
- };
- FlangerEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- FlangerEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[4] = value;
- setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
- break;
- case 6: // modulation
- this.params[1] = value / 1000;
- setAudioParam(this.oscGainNode["gain"], value / 1000, ramp, time);
- break;
- case 7: // modulation frequency
- this.params[2] = value;
- setAudioParam(this.oscNode["frequency"], value, ramp, time);
- break;
- case 8: // feedback
- this.params[3] = value / 100;
- setAudioParam(this.feedbackNode["gain"], value / 100, ramp, time);
- break;
- }
- };
- function PhaserEffect(freq, detune, q, modulation, modfreq, mix)
- {
- this.type = "phaser";
- this.params = [freq, detune, q, modulation, modfreq, mix];
- this.inputNode = createGain();
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - (mix / 2);
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix / 2;
- this.filterNode = context["createBiquadFilter"]();
- if (typeof this.filterNode["type"] === "number")
- this.filterNode["type"] = 7; // all-pass
- else
- this.filterNode["type"] = "allpass";
- this.filterNode["frequency"]["value"] = freq;
- if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
- this.filterNode["detune"]["value"] = detune;
- this.filterNode["Q"]["value"] = q;
- this.oscNode = context["createOscillator"]();
- this.oscNode["frequency"]["value"] = modfreq;
- this.oscGainNode = createGain();
- this.oscGainNode["gain"]["value"] = modulation;
- this.inputNode["connect"](this.filterNode);
- this.inputNode["connect"](this.dryNode);
- this.filterNode["connect"](this.wetNode);
- this.oscNode["connect"](this.oscGainNode);
- this.oscGainNode["connect"](this.filterNode["frequency"]);
- startSource(this.oscNode);
- };
- PhaserEffect.prototype.connectTo = function (node)
- {
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- };
- PhaserEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.filterNode["disconnect"]();
- this.oscNode["disconnect"]();
- this.oscGainNode["disconnect"]();
- this.dryNode["disconnect"]();
- this.wetNode["disconnect"]();
- };
- PhaserEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- PhaserEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[5] = value;
- setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
- break;
- case 1: // filter frequency
- this.params[0] = value;
- setAudioParam(this.filterNode["frequency"], value, ramp, time);
- break;
- case 2: // filter detune
- this.params[1] = value;
- setAudioParam(this.filterNode["detune"], value, ramp, time);
- break;
- case 3: // filter Q
- this.params[2] = value;
- setAudioParam(this.filterNode["Q"], value, ramp, time);
- break;
- case 6: // modulation
- this.params[3] = value;
- setAudioParam(this.oscGainNode["gain"], value, ramp, time);
- break;
- case 7: // modulation frequency
- this.params[4] = value;
- setAudioParam(this.oscNode["frequency"], value, ramp, time);
- break;
- }
- };
- function GainEffect(g)
- {
- this.type = "gain";
- this.params = [g];
- this.node = createGain();
- this.node["gain"]["value"] = g;
- };
- GainEffect.prototype.connectTo = function (node_)
- {
- this.node["disconnect"]();
- this.node["connect"](node_);
- };
- GainEffect.prototype.remove = function ()
- {
- this.node["disconnect"]();
- };
- GainEffect.prototype.getInputNode = function ()
- {
- return this.node;
- };
- GainEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 4: // gain
- this.params[0] = dbToLinear(value);
- setAudioParam(this.node["gain"], dbToLinear(value), ramp, time);
- break;
- }
- };
- function TremoloEffect(freq, mix)
- {
- this.type = "tremolo";
- this.params = [freq, mix];
- this.node = createGain();
- this.node["gain"]["value"] = 1 - (mix / 2);
- this.oscNode = context["createOscillator"]();
- this.oscNode["frequency"]["value"] = freq;
- this.oscGainNode = createGain();
- this.oscGainNode["gain"]["value"] = mix / 2;
- this.oscNode["connect"](this.oscGainNode);
- this.oscGainNode["connect"](this.node["gain"]);
- startSource(this.oscNode);
- };
- TremoloEffect.prototype.connectTo = function (node_)
- {
- this.node["disconnect"]();
- this.node["connect"](node_);
- };
- TremoloEffect.prototype.remove = function ()
- {
- this.oscNode["disconnect"]();
- this.oscGainNode["disconnect"]();
- this.node["disconnect"]();
- };
- TremoloEffect.prototype.getInputNode = function ()
- {
- return this.node;
- };
- TremoloEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[1] = value;
- setAudioParam(this.node["gain"]["value"], 1 - (value / 2), ramp, time);
- setAudioParam(this.oscGainNode["gain"]["value"], value / 2, ramp, time);
- break;
- case 7: // modulation frequency
- this.params[0] = value;
- setAudioParam(this.oscNode["frequency"], value, ramp, time);
- break;
- }
- };
- function RingModulatorEffect(freq, mix)
- {
- this.type = "ringmod";
- this.params = [freq, mix];
- this.inputNode = createGain();
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix;
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - mix;
- this.ringNode = createGain();
- this.ringNode["gain"]["value"] = 0;
- this.oscNode = context["createOscillator"]();
- this.oscNode["frequency"]["value"] = freq;
- this.oscNode["connect"](this.ringNode["gain"]);
- startSource(this.oscNode);
- this.inputNode["connect"](this.ringNode);
- this.inputNode["connect"](this.dryNode);
- this.ringNode["connect"](this.wetNode);
- };
- RingModulatorEffect.prototype.connectTo = function (node_)
- {
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node_);
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node_);
- };
- RingModulatorEffect.prototype.remove = function ()
- {
- this.oscNode["disconnect"]();
- this.ringNode["disconnect"]();
- this.inputNode["disconnect"]();
- this.wetNode["disconnect"]();
- this.dryNode["disconnect"]();
- };
- RingModulatorEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- RingModulatorEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[1] = value;
- setAudioParam(this.wetNode["gain"], value, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
- break;
- case 7: // modulation frequency
- this.params[0] = value;
- setAudioParam(this.oscNode["frequency"], value, ramp, time);
- break;
- }
- };
- function DistortionEffect(threshold, headroom, drive, makeupgain, mix)
- {
- this.type = "distortion";
- this.params = [threshold, headroom, drive, makeupgain, mix];
- this.inputNode = createGain();
- this.preGain = createGain();
- this.postGain = createGain();
- this.setDrive(drive, dbToLinear_nocap(makeupgain));
- this.wetNode = createGain();
- this.wetNode["gain"]["value"] = mix;
- this.dryNode = createGain();
- this.dryNode["gain"]["value"] = 1 - mix;
- this.waveShaper = context["createWaveShaper"]();
- this.curve = new Float32Array(65536);
- this.generateColortouchCurve(threshold, headroom);
- this.waveShaper.curve = this.curve;
- this.inputNode["connect"](this.preGain);
- this.inputNode["connect"](this.dryNode);
- this.preGain["connect"](this.waveShaper);
- this.waveShaper["connect"](this.postGain);
- this.postGain["connect"](this.wetNode);
- };
- DistortionEffect.prototype.setDrive = function (drive, makeupgain)
- {
- if (drive < 0.01)
- drive = 0.01;
- this.preGain["gain"]["value"] = drive;
- this.postGain["gain"]["value"] = Math.pow(1 / drive, 0.6) * makeupgain;
- };
- function e4(x, k)
- {
- return 1.0 - Math.exp(-k * x);
- }
- DistortionEffect.prototype.shape = function (x, linearThreshold, linearHeadroom)
- {
- var maximum = 1.05 * linearHeadroom * linearThreshold;
- var kk = (maximum - linearThreshold);
- var sign = x < 0 ? -1 : +1;
- var absx = x < 0 ? -x : x;
- var shapedInput = absx < linearThreshold ? absx : linearThreshold + kk * e4(absx - linearThreshold, 1.0 / kk);
- shapedInput *= sign;
- return shapedInput;
- };
- DistortionEffect.prototype.generateColortouchCurve = function (threshold, headroom)
- {
- var linearThreshold = dbToLinear_nocap(threshold);
- var linearHeadroom = dbToLinear_nocap(headroom);
- var n = 65536;
- var n2 = n / 2;
- var x = 0;
- for (var i = 0; i < n2; ++i) {
- x = i / n2;
- x = this.shape(x, linearThreshold, linearHeadroom);
- this.curve[n2 + i] = x;
- this.curve[n2 - i - 1] = -x;
- }
- };
- DistortionEffect.prototype.connectTo = function (node)
- {
- this.wetNode["disconnect"]();
- this.wetNode["connect"](node);
- this.dryNode["disconnect"]();
- this.dryNode["connect"](node);
- };
- DistortionEffect.prototype.remove = function ()
- {
- this.inputNode["disconnect"]();
- this.preGain["disconnect"]();
- this.waveShaper["disconnect"]();
- this.postGain["disconnect"]();
- this.wetNode["disconnect"]();
- this.dryNode["disconnect"]();
- };
- DistortionEffect.prototype.getInputNode = function ()
- {
- return this.inputNode;
- };
- DistortionEffect.prototype.setParam = function(param, value, ramp, time)
- {
- switch (param) {
- case 0: // mix
- value = value / 100;
- if (value < 0) value = 0;
- if (value > 1) value = 1;
- this.params[4] = value;
- setAudioParam(this.wetNode["gain"], value, ramp, time);
- setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
- break;
- }
- };
- function CompressorEffect(threshold, knee, ratio, attack, release)
- {
- this.type = "compressor";
- this.params = [threshold, knee, ratio, attack, release];
- this.node = context["createDynamicsCompressor"]();
- try {
- this.node["threshold"]["value"] = threshold;
- this.node["knee"]["value"] = knee;
- this.node["ratio"]["value"] = ratio;
- this.node["attack"]["value"] = attack;
- this.node["release"]["value"] = release;
- }
- catch (e) {}
- };
- CompressorEffect.prototype.connectTo = function (node_)
- {
- this.node["disconnect"]();
- this.node["connect"](node_);
- };
- CompressorEffect.prototype.remove = function ()
- {
- this.node["disconnect"]();
- };
- CompressorEffect.prototype.getInputNode = function ()
- {
- return this.node;
- };
- CompressorEffect.prototype.setParam = function(param, value, ramp, time)
- {
- };
- function AnalyserEffect(fftSize, smoothing)
- {
- this.type = "analyser";
- this.params = [fftSize, smoothing];
- this.node = context["createAnalyser"]();
- this.node["fftSize"] = fftSize;
- this.node["smoothingTimeConstant"] = smoothing;
- this.freqBins = new Float32Array(this.node["frequencyBinCount"]);
- this.signal = new Uint8Array(fftSize);
- this.peak = 0;
- this.rms = 0;
- };
- AnalyserEffect.prototype.tick = function ()
- {
- this.node["getFloatFrequencyData"](this.freqBins);
- this.node["getByteTimeDomainData"](this.signal);
- var fftSize = this.node["fftSize"];
- var i = 0;
- this.peak = 0;
- var rmsSquaredSum = 0;
- var s = 0;
- for ( ; i < fftSize; i++)
- {
- s = (this.signal[i] - 128) / 128;
- if (s < 0)
- s = -s;
- if (this.peak < s)
- this.peak = s;
- rmsSquaredSum += s * s;
- }
- this.peak = linearToDb(this.peak);
- this.rms = linearToDb(Math.sqrt(rmsSquaredSum / fftSize));
- };
- AnalyserEffect.prototype.connectTo = function (node_)
- {
- this.node["disconnect"]();
- this.node["connect"](node_);
- };
- AnalyserEffect.prototype.remove = function ()
- {
- this.node["disconnect"]();
- };
- AnalyserEffect.prototype.getInputNode = function ()
- {
- return this.node;
- };
- AnalyserEffect.prototype.setParam = function(param, value, ramp, time)
- {
- };
- function ObjectTracker()
- {
- this.obj = null;
- this.loadUid = 0;
- };
- ObjectTracker.prototype.setObject = function (obj_)
- {
- this.obj = obj_;
- };
- ObjectTracker.prototype.hasObject = function ()
- {
- return !!this.obj;
- };
- ObjectTracker.prototype.tick = function (dt)
- {
- };
- function C2AudioBuffer(src_, is_music)
- {
- this.src = src_;
- this.myapi = api;
- this.is_music = is_music;
- this.added_end_listener = false;
- var self = this;
- this.outNode = null;
- this.mediaSourceNode = null;
- this.panWhenReady = []; // for web audio API positioned sounds
- this.seekWhenReady = 0;
- this.pauseWhenReady = false;
- this.supportWebAudioAPI = false;
- this.failedToLoad = false;
- this.wasEverReady = false; // if a buffer is ever marked as ready, it's permanently considered ready after then.
- if (api === API_WEBAUDIO && is_music && !playMusicAsSoundWorkaround)
- {
- this.myapi = API_HTML5;
- this.outNode = createGain();
- }
- this.bufferObject = null; // actual audio object
- this.audioData = null; // web audio api: ajax request result (compressed audio that needs decoding)
- var request;
- switch (this.myapi) {
- case API_HTML5:
- this.bufferObject = new Audio();
- this.bufferObject.crossOrigin = "anonymous";
- this.bufferObject.addEventListener("canplaythrough", function () {
- self.wasEverReady = true; // update loaded state so preload is considered complete
- });
- if (api === API_WEBAUDIO && context["createMediaElementSource"] && !/wiiu/i.test(navigator.userAgent))
- {
- this.supportWebAudioAPI = true; // can be routed through web audio api
- this.bufferObject.addEventListener("canplay", function ()
- {
- if (!self.mediaSourceNode && self.bufferObject)
- {
- self.mediaSourceNode = context["createMediaElementSource"](self.bufferObject);
- self.mediaSourceNode["connect"](self.outNode);
- }
- });
- }
- this.bufferObject.autoplay = false; // this is only a source buffer, not an instance
- this.bufferObject.preload = "auto";
- this.bufferObject.src = src_;
- break;
- case API_WEBAUDIO:
- if (audRuntime.isWKWebView)
- {
- audRuntime.fetchLocalFileViaCordovaAsArrayBuffer(src_, function (arrayBuffer)
- {
- self.audioData = arrayBuffer;
- self.decodeAudioBuffer();
- }, function (err)
- {
- self.failedToLoad = true;
- });
- }
- else
- {
- request = new XMLHttpRequest();
- request.open("GET", src_, true);
- request.responseType = "arraybuffer";
- request.onload = function () {
- self.audioData = request.response;
- self.decodeAudioBuffer();
- };
- request.onerror = function () {
- self.failedToLoad = true;
- };
- request.send();
- }
- break;
- case API_CORDOVA:
- this.bufferObject = true;
- break;
- case API_APPMOBI:
- this.bufferObject = true;
- break;
- }
- };
- C2AudioBuffer.prototype.release = function ()
- {
- var i, len, j, a;
- for (i = 0, j = 0, len = audioInstances.length; i < len; ++i)
- {
- a = audioInstances[i];
- audioInstances[j] = a;
- if (a.buffer === this)
- a.stop();
- else
- ++j; // keep
- }
- audioInstances.length = j;
- if (this.mediaSourceNode)
- {
- this.mediaSourceNode["disconnect"]();
- this.mediaSourceNode = null;
- }
- if (this.outNode)
- {
- this.outNode["disconnect"]();
- this.outNode = null;
- }
- this.bufferObject = null;
- this.audioData = null;
- };
- C2AudioBuffer.prototype.decodeAudioBuffer = function ()
- {
- if (this.bufferObject || !this.audioData)
- return; // audio already decoded or AJAX request not yet complete
- var self = this;
- if (context["decodeAudioData"])
- {
- context["decodeAudioData"](this.audioData, function (buffer) {
- self.bufferObject = buffer;
- self.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
- var p, i, len, a;
- if (!cr.is_undefined(self.playTagWhenReady) && !silent)
- {
- if (self.panWhenReady.length)
- {
- for (i = 0, len = self.panWhenReady.length; i < len; i++)
- {
- p = self.panWhenReady[i];
- a = new C2AudioInstance(self, p.thistag);
- a.setPannerEnabled(true);
- if (typeof p.objUid !== "undefined")
- {
- p.obj = audRuntime.getObjectByUID(p.objUid);
- if (!p.obj)
- continue;
- }
- if (p.obj)
- {
- var px = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, true);
- var py = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, false);
- a.setPan(px, py, cr.to_degrees(p.obj.angle - p.obj.layer.getAngle()), p.ia, p.oa, p.og);
- a.setObject(p.obj);
- }
- else
- {
- a.setPan(p.x, p.y, p.a, p.ia, p.oa, p.og);
- }
- a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
- if (self.pauseWhenReady)
- a.pause();
- audioInstances.push(a);
- }
- cr.clearArray(self.panWhenReady);
- }
- else
- {
- a = new C2AudioInstance(self, self.playTagWhenReady || ""); // sometimes playTagWhenReady is not set - TODO: why?
- a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
- if (self.pauseWhenReady)
- a.pause();
- audioInstances.push(a);
- }
- }
- else if (!cr.is_undefined(self.convolveWhenReady))
- {
- var convolveNode = self.convolveWhenReady.convolveNode;
- convolveNode["normalize"] = self.normalizeWhenReady;
- convolveNode["buffer"] = buffer;
- }
- }, function (e) {
- self.failedToLoad = true;
- });
- }
- else
- {
- this.bufferObject = context["createBuffer"](this.audioData, false);
- this.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
- if (!cr.is_undefined(this.playTagWhenReady) && !silent)
- {
- var a = new C2AudioInstance(this, this.playTagWhenReady);
- a.play(this.loopWhenReady, this.volumeWhenReady, this.seekWhenReady);
- if (this.pauseWhenReady)
- a.pause();
- audioInstances.push(a);
- }
- else if (!cr.is_undefined(this.convolveWhenReady))
- {
- var convolveNode = this.convolveWhenReady.convolveNode;
- convolveNode["normalize"] = this.normalizeWhenReady;
- convolveNode["buffer"] = this.bufferObject;
- }
- }
- };
- C2AudioBuffer.prototype.isLoaded = function ()
- {
- switch (this.myapi) {
- case API_HTML5:
- var ret = this.bufferObject["readyState"] >= 4; // HAVE_ENOUGH_DATA
- if (ret)
- this.wasEverReady = true;
- return ret || this.wasEverReady;
- case API_WEBAUDIO:
- return !!this.audioData || !!this.bufferObject;
- case API_CORDOVA:
- return true;
- case API_APPMOBI:
- return true;
- }
- return false;
- };
- C2AudioBuffer.prototype.isLoadedAndDecoded = function ()
- {
- switch (this.myapi) {
- case API_HTML5:
- return this.isLoaded(); // no distinction between loaded and decoded in HTML5 audio, just rely on ready state
- case API_WEBAUDIO:
- return !!this.bufferObject;
- case API_CORDOVA:
- return true;
- case API_APPMOBI:
- return true;
- }
- return false;
- };
- C2AudioBuffer.prototype.hasFailedToLoad = function ()
- {
- switch (this.myapi) {
- case API_HTML5:
- return !!this.bufferObject["error"];
- case API_WEBAUDIO:
- return this.failedToLoad;
- }
- return false;
- };
- function C2AudioInstance(buffer_, tag_)
- {
- var self = this;
- this.tag = tag_;
- this.fresh = true;
- this.stopped = true;
- this.src = buffer_.src;
- this.buffer = buffer_;
- this.myapi = api;
- this.is_music = buffer_.is_music;
- this.playbackRate = 1;
- this.hasPlaybackEnded = true; // ended flag
- this.resume_me = false; // make sure resumes when leaving suspend
- this.is_paused = false;
- this.resume_position = 0; // for web audio api to resume from correct playback position
- this.looping = false;
- this.is_muted = false;
- this.is_silent = false;
- this.volume = 1;
- this.onended_handler = function (e)
- {
- if (self.is_paused || self.resume_me)
- return;
- var bufferThatEnded = this;
- if (!bufferThatEnded)
- bufferThatEnded = e.target;
- if (bufferThatEnded !== self.active_buffer)
- return;
- self.hasPlaybackEnded = true;
- self.stopped = true;
- audTag = self.tag;
- audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
- };
- this.active_buffer = null;
- this.isTimescaled = ((timescale_mode === 1 && !this.is_music) || timescale_mode === 2);
- this.mutevol = 1;
- this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum);
- this.gainNode = null;
- this.pannerNode = null;
- this.pannerEnabled = false;
- this.objectTracker = null;
- this.panX = 0;
- this.panY = 0;
- this.panAngle = 0;
- this.panConeInner = 0;
- this.panConeOuter = 0;
- this.panConeOuterGain = 0;
- this.instanceObject = null;
- var add_end_listener = false;
- if (this.myapi === API_WEBAUDIO && this.buffer.myapi === API_HTML5 && !this.buffer.supportWebAudioAPI)
- this.myapi = API_HTML5;
- switch (this.myapi) {
- case API_HTML5:
- if (this.is_music)
- {
- this.instanceObject = buffer_.bufferObject;
- add_end_listener = !buffer_.added_end_listener;
- buffer_.added_end_listener = true;
- }
- else
- {
- this.instanceObject = new Audio();
- this.instanceObject.crossOrigin = "anonymous";
- this.instanceObject.autoplay = false;
- this.instanceObject.src = buffer_.bufferObject.src;
- add_end_listener = true;
- }
- if (add_end_listener)
- {
- this.instanceObject.addEventListener('ended', function () {
- audTag = self.tag;
- self.stopped = true;
- audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
- });
- }
- break;
- case API_WEBAUDIO:
- this.gainNode = createGain();
- this.gainNode["connect"](getDestinationForTag(tag_));
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- if (buffer_.bufferObject)
- {
- this.instanceObject = context["createBufferSource"]();
- this.instanceObject["buffer"] = buffer_.bufferObject;
- this.instanceObject["connect"](this.gainNode);
- }
- }
- else
- {
- this.instanceObject = this.buffer.bufferObject; // reference the audio element
- this.buffer.outNode["connect"](this.gainNode);
- if (!this.buffer.added_end_listener)
- {
- this.buffer.added_end_listener = true;
- this.buffer.bufferObject.addEventListener('ended', function () {
- audTag = self.tag;
- self.stopped = true;
- audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
- });
- }
- }
- break;
- case API_CORDOVA:
- this.instanceObject = new window["Media"](appPath + this.src, null, null, function (status) {
- if (status === window["Media"]["MEDIA_STOPPED"])
- {
- self.hasPlaybackEnded = true;
- self.stopped = true;
- audTag = self.tag;
- audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
- }
- });
- break;
- case API_APPMOBI:
- this.instanceObject = true;
- break;
- }
- };
- C2AudioInstance.prototype.hasEnded = function ()
- {
- var time;
- switch (this.myapi) {
- case API_HTML5:
- return this.instanceObject.ended;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- if (!this.fresh && !this.stopped && this.instanceObject["loop"])
- return false;
- if (this.is_paused)
- return false;
- return this.hasPlaybackEnded;
- }
- else
- return this.instanceObject.ended;
- case API_CORDOVA:
- return this.hasPlaybackEnded;
- case API_APPMOBI:
- true; // recycling an AppMobi sound does not matter because it will just do another throwaway playSound
- }
- return true;
- };
- C2AudioInstance.prototype.canBeRecycled = function ()
- {
- if (this.fresh || this.stopped)
- return true; // not yet used or is not playing
- return this.hasEnded();
- };
- C2AudioInstance.prototype.setPannerEnabled = function (enable_)
- {
- if (api !== API_WEBAUDIO)
- return;
- if (!this.pannerEnabled && enable_)
- {
- if (!this.gainNode)
- return;
- if (!this.pannerNode)
- {
- this.pannerNode = context["createPanner"]();
- if (typeof this.pannerNode["panningModel"] === "number")
- this.pannerNode["panningModel"] = panningModel;
- else
- this.pannerNode["panningModel"] = ["equalpower", "HRTF", "soundfield"][panningModel];
- if (typeof this.pannerNode["distanceModel"] === "number")
- this.pannerNode["distanceModel"] = distanceModel;
- else
- this.pannerNode["distanceModel"] = ["linear", "inverse", "exponential"][distanceModel];
- this.pannerNode["refDistance"] = refDistance;
- this.pannerNode["maxDistance"] = maxDistance;
- this.pannerNode["rolloffFactor"] = rolloffFactor;
- }
- this.gainNode["disconnect"]();
- this.gainNode["connect"](this.pannerNode);
- this.pannerNode["connect"](getDestinationForTag(this.tag));
- this.pannerEnabled = true;
- }
- else if (this.pannerEnabled && !enable_)
- {
- if (!this.gainNode)
- return;
- this.pannerNode["disconnect"]();
- this.gainNode["disconnect"]();
- this.gainNode["connect"](getDestinationForTag(this.tag));
- this.pannerEnabled = false;
- }
- };
- C2AudioInstance.prototype.setPan = function (x, y, angle, innerangle, outerangle, outergain)
- {
- if (!this.pannerEnabled || api !== API_WEBAUDIO)
- return;
- this.pannerNode["setPosition"](x, y, 0);
- this.pannerNode["setOrientation"](Math.cos(cr.to_radians(angle)), Math.sin(cr.to_radians(angle)), 0);
- this.pannerNode["coneInnerAngle"] = innerangle;
- this.pannerNode["coneOuterAngle"] = outerangle;
- this.pannerNode["coneOuterGain"] = outergain;
- this.panX = x;
- this.panY = y;
- this.panAngle = angle;
- this.panConeInner = innerangle;
- this.panConeOuter = outerangle;
- this.panConeOuterGain = outergain;
- };
- C2AudioInstance.prototype.setObject = function (o)
- {
- if (!this.pannerEnabled || api !== API_WEBAUDIO)
- return;
- if (!this.objectTracker)
- this.objectTracker = new ObjectTracker();
- this.objectTracker.setObject(o);
- };
- C2AudioInstance.prototype.tick = function (dt)
- {
- if (!this.pannerEnabled || api !== API_WEBAUDIO || !this.objectTracker || !this.objectTracker.hasObject() || !this.isPlaying())
- {
- return;
- }
- this.objectTracker.tick(dt);
- var inst = this.objectTracker.obj;
- var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
- var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
- this.pannerNode["setPosition"](px, py, 0);
- var a = 0;
- if (typeof this.objectTracker.obj.angle !== "undefined")
- {
- a = inst.angle - inst.layer.getAngle();
- this.pannerNode["setOrientation"](Math.cos(a), Math.sin(a), 0);
- }
- };
- C2AudioInstance.prototype.play = function (looping, vol, fromPosition, scheduledTime)
- {
- var instobj = this.instanceObject;
- this.looping = looping;
- this.volume = vol;
- var seekPos = fromPosition || 0;
- scheduledTime = scheduledTime || 0;
- switch (this.myapi) {
- case API_HTML5:
- if (instobj.playbackRate !== 1.0)
- instobj.playbackRate = 1.0;
- if (instobj.volume !== vol * masterVolume)
- instobj.volume = vol * masterVolume;
- if (instobj.loop !== looping)
- instobj.loop = looping;
- if (instobj.muted)
- instobj.muted = false;
- if (instobj.currentTime !== seekPos)
- {
- try {
- instobj.currentTime = seekPos;
- }
- catch (err)
- {
-;
- }
- }
- tryPlayAudioElement(this);
- break;
- case API_WEBAUDIO:
- this.muted = false;
- this.mutevol = 1;
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.gainNode["gain"]["value"] = vol * masterVolume;
- if (!this.fresh)
- {
- this.instanceObject = context["createBufferSource"]();
- this.instanceObject["buffer"] = this.buffer.bufferObject;
- this.instanceObject["connect"](this.gainNode);
- }
- this.instanceObject["onended"] = this.onended_handler;
- this.active_buffer = this.instanceObject;
- this.instanceObject.loop = looping;
- this.hasPlaybackEnded = false;
- if (seekPos === 0)
- startSource(this.instanceObject, scheduledTime);
- else
- startSourceAt(this.instanceObject, seekPos, this.getDuration(), scheduledTime);
- }
- else
- {
- if (instobj.playbackRate !== 1.0)
- instobj.playbackRate = 1.0;
- if (instobj.loop !== looping)
- instobj.loop = looping;
- instobj.volume = vol * masterVolume;
- if (instobj.currentTime !== seekPos)
- {
- try {
- instobj.currentTime = seekPos;
- }
- catch (err)
- {
-;
- }
- }
- tryPlayAudioElement(this);
- }
- break;
- case API_CORDOVA:
- if ((!this.fresh && this.stopped) || seekPos !== 0)
- instobj["seekTo"](seekPos);
- instobj["play"]();
- this.hasPlaybackEnded = false;
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["playSound"](this.src, looping);
- else
- AppMobi["player"]["playSound"](this.src, looping);
- break;
- }
- this.playbackRate = 1;
- this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - seekPos;
- this.fresh = false;
- this.stopped = false;
- this.is_paused = false;
- };
- C2AudioInstance.prototype.stop = function ()
- {
- switch (this.myapi) {
- case API_HTML5:
- if (!this.instanceObject.paused)
- this.instanceObject.pause();
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- stopSource(this.instanceObject);
- else
- {
- if (!this.instanceObject.paused)
- this.instanceObject.pause();
- }
- break;
- case API_CORDOVA:
- this.instanceObject["stop"]();
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["stopSound"](this.src);
- break;
- }
- this.stopped = true;
- this.is_paused = false;
- };
- C2AudioInstance.prototype.pause = function ()
- {
- if (this.fresh || this.stopped || this.hasEnded() || this.is_paused)
- return;
- switch (this.myapi) {
- case API_HTML5:
- if (!this.instanceObject.paused)
- this.instanceObject.pause();
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.resume_position = this.getPlaybackTime(true);
- if (this.looping)
- this.resume_position = this.resume_position % this.getDuration();
- this.is_paused = true;
- stopSource(this.instanceObject);
- }
- else
- {
- if (!this.instanceObject.paused)
- this.instanceObject.pause();
- }
- break;
- case API_CORDOVA:
- this.instanceObject["pause"]();
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["stopSound"](this.src);
- break;
- }
- this.is_paused = true;
- };
- C2AudioInstance.prototype.resume = function ()
- {
- if (this.fresh || this.stopped || this.hasEnded() || !this.is_paused)
- return;
- switch (this.myapi) {
- case API_HTML5:
- tryPlayAudioElement(this);
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.instanceObject = context["createBufferSource"]();
- this.instanceObject["buffer"] = this.buffer.bufferObject;
- this.instanceObject["connect"](this.gainNode);
- this.instanceObject["onended"] = this.onended_handler;
- this.active_buffer = this.instanceObject;
- this.instanceObject.loop = this.looping;
- this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
- this.updatePlaybackRate();
- this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
- startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
- }
- else
- {
- tryPlayAudioElement(this);
- }
- break;
- case API_CORDOVA:
- this.instanceObject["play"]();
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["resumeSound"](this.src);
- break;
- }
- this.is_paused = false;
- };
- C2AudioInstance.prototype.seek = function (pos)
- {
- if (this.fresh || this.stopped || this.hasEnded())
- return;
- switch (this.myapi) {
- case API_HTML5:
- try {
- this.instanceObject.currentTime = pos;
- }
- catch (e) {}
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- if (this.is_paused)
- this.resume_position = pos;
- else
- {
- this.pause();
- this.resume_position = pos;
- this.resume();
- }
- }
- else
- {
- try {
- this.instanceObject.currentTime = pos;
- }
- catch (e) {}
- }
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["seekSound"](this.src, pos);
- break;
- }
- };
- C2AudioInstance.prototype.reconnect = function (toNode)
- {
- if (this.myapi !== API_WEBAUDIO)
- return;
- if (this.pannerEnabled)
- {
- this.pannerNode["disconnect"]();
- this.pannerNode["connect"](toNode);
- }
- else
- {
- this.gainNode["disconnect"]();
- this.gainNode["connect"](toNode);
- }
- };
- C2AudioInstance.prototype.getDuration = function (applyPlaybackRate)
- {
- var ret = 0;
- switch (this.myapi) {
- case API_HTML5:
- if (typeof this.instanceObject.duration !== "undefined")
- ret = this.instanceObject.duration;
- break;
- case API_WEBAUDIO:
- ret = this.buffer.bufferObject["duration"];
- break;
- case API_CORDOVA:
- ret = this.instanceObject["getDuration"]();
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- ret = AppMobi["context"]["getDurationSound"](this.src);
- break;
- }
- if (applyPlaybackRate)
- ret /= (this.playbackRate || 0.001); // avoid divide-by-zero
- return ret;
- };
- C2AudioInstance.prototype.getPlaybackTime = function (applyPlaybackRate)
- {
- var duration = this.getDuration();
- var ret = 0;
- switch (this.myapi) {
- case API_HTML5:
- if (typeof this.instanceObject.currentTime !== "undefined")
- ret = this.instanceObject.currentTime;
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- if (this.is_paused)
- return this.resume_position;
- else
- ret = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.startTime;
- }
- else if (typeof this.instanceObject.currentTime !== "undefined")
- ret = this.instanceObject.currentTime;
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- ret = AppMobi["context"]["getPlaybackTimeSound"](this.src);
- break;
- }
- if (applyPlaybackRate)
- ret *= this.playbackRate;
- if (!this.looping && ret > duration)
- ret = duration;
- return ret;
- };
- C2AudioInstance.prototype.isPlaying = function ()
- {
- return !this.is_paused && !this.fresh && !this.stopped && !this.hasEnded();
- };
- C2AudioInstance.prototype.shouldSave = function ()
- {
- return !this.fresh && !this.stopped && !this.hasEnded();
- };
- C2AudioInstance.prototype.setVolume = function (v)
- {
- this.volume = v;
- this.updateVolume();
- };
- C2AudioInstance.prototype.updateVolume = function ()
- {
- var volToSet = this.volume * masterVolume;
- if (!isFinite(volToSet))
- volToSet = 0; // HTMLMediaElement throws if setting non-finite volume
- switch (this.myapi) {
- case API_HTML5:
- if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
- this.instanceObject.volume = volToSet;
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.gainNode["gain"]["value"] = volToSet * this.mutevol;
- }
- else
- {
- if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
- this.instanceObject.volume = volToSet;
- }
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- break;
- }
- };
- C2AudioInstance.prototype.getVolume = function ()
- {
- return this.volume;
- };
- C2AudioInstance.prototype.doSetMuted = function (m)
- {
- switch (this.myapi) {
- case API_HTML5:
- if (this.instanceObject.muted !== !!m)
- this.instanceObject.muted = !!m;
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.mutevol = (m ? 0 : 1);
- this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
- }
- else
- {
- if (this.instanceObject.muted !== !!m)
- this.instanceObject.muted = !!m;
- }
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- break;
- }
- };
- C2AudioInstance.prototype.setMuted = function (m)
- {
- this.is_muted = !!m;
- this.doSetMuted(this.is_muted || this.is_silent);
- };
- C2AudioInstance.prototype.setSilent = function (m)
- {
- this.is_silent = !!m;
- this.doSetMuted(this.is_muted || this.is_silent);
- };
- C2AudioInstance.prototype.setLooping = function (l)
- {
- this.looping = l;
- switch (this.myapi) {
- case API_HTML5:
- if (this.instanceObject.loop !== !!l)
- this.instanceObject.loop = !!l;
- break;
- case API_WEBAUDIO:
- if (this.instanceObject.loop !== !!l)
- this.instanceObject.loop = !!l;
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- if (audRuntime.isDirectCanvas)
- AppMobi["context"]["setLoopingSound"](this.src, l);
- break;
- }
- };
- C2AudioInstance.prototype.setPlaybackRate = function (r)
- {
- this.playbackRate = r;
- this.updatePlaybackRate();
- };
- C2AudioInstance.prototype.updatePlaybackRate = function ()
- {
- var r = this.playbackRate;
- if (this.isTimescaled)
- r *= audRuntime.timescale;
- switch (this.myapi) {
- case API_HTML5:
- if (this.instanceObject.playbackRate !== r)
- this.instanceObject.playbackRate = r;
- break;
- case API_WEBAUDIO:
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- if (this.instanceObject["playbackRate"]["value"] !== r)
- this.instanceObject["playbackRate"]["value"] = r;
- }
- else
- {
- if (this.instanceObject.playbackRate !== r)
- this.instanceObject.playbackRate = r;
- }
- break;
- case API_CORDOVA:
- break;
- case API_APPMOBI:
- break;
- }
- };
- C2AudioInstance.prototype.setSuspended = function (s)
- {
- switch (this.myapi) {
- case API_HTML5:
- if (s)
- {
- if (this.isPlaying())
- {
- this.resume_me = true;
- this.instanceObject["pause"]();
- }
- else
- this.resume_me = false;
- }
- else
- {
- if (this.resume_me)
- {
- this.instanceObject["play"]();
- this.resume_me = false;
- }
- }
- break;
- case API_WEBAUDIO:
- if (s)
- {
- if (this.isPlaying())
- {
- this.resume_me = true;
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.resume_position = this.getPlaybackTime(true);
- if (this.looping)
- this.resume_position = this.resume_position % this.getDuration();
- stopSource(this.instanceObject);
- }
- else
- this.instanceObject["pause"]();
- }
- else
- this.resume_me = false;
- }
- else
- {
- if (this.resume_me)
- {
- if (this.buffer.myapi === API_WEBAUDIO)
- {
- this.instanceObject = context["createBufferSource"]();
- this.instanceObject["buffer"] = this.buffer.bufferObject;
- this.instanceObject["connect"](this.gainNode);
- this.instanceObject["onended"] = this.onended_handler;
- this.active_buffer = this.instanceObject;
- this.instanceObject.loop = this.looping;
- this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
- this.updatePlaybackRate();
- this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
- startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
- }
- else
- {
- this.instanceObject["play"]();
- }
- this.resume_me = false;
- }
- }
- break;
- case API_CORDOVA:
- if (s)
- {
- if (this.isPlaying())
- {
- this.instanceObject["pause"]();
- this.resume_me = true;
- }
- else
- this.resume_me = false;
- }
- else
- {
- if (this.resume_me)
- {
- this.resume_me = false;
- this.instanceObject["play"]();
- }
- }
- break;
- case API_APPMOBI:
- break;
- }
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- audRuntime = this.runtime;
- audInst = this;
- this.listenerTracker = null;
- this.listenerZ = -600;
- if (this.runtime.isWKWebView)
- playMusicAsSoundWorkaround = true;
- if ((this.runtime.isiOS || (this.runtime.isAndroid && (this.runtime.isChrome || this.runtime.isAndroidStockBrowser))) && !this.runtime.isCrosswalk && !this.runtime.isDomFree && !this.runtime.isAmazonWebApp && !playMusicAsSoundWorkaround)
- {
- useNextTouchWorkaround = true;
- }
- context = null;
- if (typeof AudioContext !== "undefined")
- {
- api = API_WEBAUDIO;
- context = new AudioContext();
- }
- else if (typeof webkitAudioContext !== "undefined")
- {
- api = API_WEBAUDIO;
- context = new webkitAudioContext();
- }
- if (this.runtime.isiOS && context)
- {
- if (context.close)
- context.close();
- if (typeof AudioContext !== "undefined")
- context = new AudioContext();
- else if (typeof webkitAudioContext !== "undefined")
- context = new webkitAudioContext();
- }
- if (api !== API_WEBAUDIO)
- {
- if (this.runtime.isCordova && typeof window["Media"] !== "undefined")
- api = API_CORDOVA;
- else if (this.runtime.isAppMobi)
- api = API_APPMOBI;
- }
- if (api === API_CORDOVA)
- {
- appPath = location.href;
- var i = appPath.lastIndexOf("/");
- if (i > -1)
- appPath = appPath.substr(0, i + 1);
- appPath = appPath.replace("file://", "");
- }
- if (this.runtime.isSafari && this.runtime.isWindows && typeof Audio === "undefined")
- {
- alert("It looks like you're using Safari for Windows without Quicktime. Audio cannot be played until Quicktime is installed.");
- this.runtime.DestroyInstance(this);
- }
- else
- {
- if (this.runtime.isDirectCanvas)
- useOgg = this.runtime.isAndroid; // AAC on iOS, OGG on Android
- else
- {
- try {
- useOgg = !!(new Audio().canPlayType('audio/ogg; codecs="vorbis"')) &&
- !this.runtime.isWindows10;
- }
- catch (e)
- {
- useOgg = false;
- }
- }
- switch (api) {
- case API_HTML5:
-;
- break;
- case API_WEBAUDIO:
-;
- break;
- case API_CORDOVA:
-;
- break;
- case API_APPMOBI:
-;
- break;
- default:
-;
- }
- this.runtime.tickMe(this);
- }
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onCreate = function ()
- {
- this.runtime.audioInstance = this;
- timescale_mode = this.properties[0]; // 0 = off, 1 = sounds only, 2 = all
- this.saveload = this.properties[1]; // 0 = all, 1 = sounds only, 2 = music only, 3 = none
- this.playinbackground = (this.properties[2] !== 0);
- this.nextPlayTime = 0;
- panningModel = this.properties[3]; // 0 = equalpower, 1 = hrtf, 3 = soundfield
- distanceModel = this.properties[4]; // 0 = linear, 1 = inverse, 2 = exponential
- this.listenerZ = -this.properties[5];
- refDistance = this.properties[6];
- maxDistance = this.properties[7];
- rolloffFactor = this.properties[8];
- this.listenerTracker = new ObjectTracker();
- var draw_width = (this.runtime.draw_width || this.runtime.width);
- var draw_height = (this.runtime.draw_height || this.runtime.height);
- if (api === API_WEBAUDIO)
- {
- context["listener"]["setPosition"](draw_width / 2, draw_height / 2, this.listenerZ);
- context["listener"]["setOrientation"](0, 0, 1, 0, -1, 0);
- window["c2OnAudioMicStream"] = function (localMediaStream, tag)
- {
- if (micSource)
- micSource["disconnect"]();
- micTag = tag.toLowerCase();
- micSource = context["createMediaStreamSource"](localMediaStream);
- micSource["connect"](getDestinationForTag(micTag));
- };
- }
- this.runtime.addSuspendCallback(function(s)
- {
- audInst.onSuspend(s);
- });
- var self = this;
- this.runtime.addDestroyCallback(function (inst)
- {
- self.onInstanceDestroyed(inst);
- });
- };
- instanceProto.onInstanceDestroyed = function (inst)
- {
- var i, len, a;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- if (a.objectTracker)
- {
- if (a.objectTracker.obj === inst)
- {
- a.objectTracker.obj = null;
- if (a.pannerEnabled && a.isPlaying() && a.looping)
- a.stop();
- }
- }
- }
- if (this.listenerTracker.obj === inst)
- this.listenerTracker.obj = null;
- };
- instanceProto.saveToJSON = function ()
- {
- var o = {
- "silent": silent,
- "masterVolume": masterVolume,
- "listenerZ": this.listenerZ,
- "listenerUid": this.listenerTracker.hasObject() ? this.listenerTracker.obj.uid : -1,
- "playing": [],
- "effects": {}
- };
- var playingarr = o["playing"];
- var i, len, a, d, p, panobj, playbackTime;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- if (!a.shouldSave())
- continue; // no need to save stopped sounds
- if (this.saveload === 3) // not saving/loading any sounds/music
- continue;
- if (a.is_music && this.saveload === 1) // not saving/loading music
- continue;
- if (!a.is_music && this.saveload === 2) // not saving/loading sound
- continue;
- playbackTime = a.getPlaybackTime();
- if (a.looping)
- playbackTime = playbackTime % a.getDuration();
- d = {
- "tag": a.tag,
- "buffersrc": a.buffer.src,
- "is_music": a.is_music,
- "playbackTime": playbackTime,
- "volume": a.volume,
- "looping": a.looping,
- "muted": a.is_muted,
- "playbackRate": a.playbackRate,
- "paused": a.is_paused,
- "resume_position": a.resume_position
- };
- if (a.pannerEnabled)
- {
- d["pan"] = {};
- panobj = d["pan"];
- if (a.objectTracker && a.objectTracker.hasObject())
- {
- panobj["objUid"] = a.objectTracker.obj.uid;
- }
- else
- {
- panobj["x"] = a.panX;
- panobj["y"] = a.panY;
- panobj["a"] = a.panAngle;
- }
- panobj["ia"] = a.panConeInner;
- panobj["oa"] = a.panConeOuter;
- panobj["og"] = a.panConeOuterGain;
- }
- playingarr.push(d);
- }
- var fxobj = o["effects"];
- var fxarr;
- for (p in effects)
- {
- if (effects.hasOwnProperty(p))
- {
- fxarr = [];
- for (i = 0, len = effects[p].length; i < len; i++)
- {
- fxarr.push({ "type": effects[p][i].type, "params": effects[p][i].params });
- }
- fxobj[p] = fxarr;
- }
- }
- return o;
- };
- var objectTrackerUidsToLoad = [];
- instanceProto.loadFromJSON = function (o)
- {
- var setSilent = o["silent"];
- masterVolume = o["masterVolume"];
- this.listenerZ = o["listenerZ"];
- this.listenerTracker.setObject(null);
- var listenerUid = o["listenerUid"];
- if (listenerUid !== -1)
- {
- this.listenerTracker.loadUid = listenerUid;
- objectTrackerUidsToLoad.push(this.listenerTracker);
- }
- var playingarr = o["playing"];
- var i, len, d, src, is_music, tag, playbackTime, looping, vol, b, a, p, pan, panObjUid;
- if (this.saveload !== 3)
- {
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- if (a.is_music && this.saveload === 1)
- continue; // only saving/loading sound: leave music playing
- if (!a.is_music && this.saveload === 2)
- continue; // only saving/loading music: leave sound playing
- a.stop();
- }
- }
- var fxarr, fxtype, fxparams, fx;
- for (p in effects)
- {
- if (effects.hasOwnProperty(p))
- {
- for (i = 0, len = effects[p].length; i < len; i++)
- effects[p][i].remove();
- }
- }
- cr.wipe(effects);
- for (p in o["effects"])
- {
- if (o["effects"].hasOwnProperty(p))
- {
- fxarr = o["effects"][p];
- for (i = 0, len = fxarr.length; i < len; i++)
- {
- fxtype = fxarr[i]["type"];
- fxparams = fxarr[i]["params"];
- switch (fxtype) {
- case "filter":
- addEffectForTag(p, new FilterEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
- break;
- case "delay":
- addEffectForTag(p, new DelayEffect(fxparams[0], fxparams[1], fxparams[2]));
- break;
- case "convolve":
- src = fxparams[2];
- b = this.getAudioBuffer(src, false);
- if (b.bufferObject)
- {
- fx = new ConvolveEffect(b.bufferObject, fxparams[0], fxparams[1], src);
- }
- else
- {
- fx = new ConvolveEffect(null, fxparams[0], fxparams[1], src);
- b.normalizeWhenReady = fxparams[0];
- b.convolveWhenReady = fx;
- }
- addEffectForTag(p, fx);
- break;
- case "flanger":
- addEffectForTag(p, new FlangerEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
- break;
- case "phaser":
- addEffectForTag(p, new PhaserEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
- break;
- case "gain":
- addEffectForTag(p, new GainEffect(fxparams[0]));
- break;
- case "tremolo":
- addEffectForTag(p, new TremoloEffect(fxparams[0], fxparams[1]));
- break;
- case "ringmod":
- addEffectForTag(p, new RingModulatorEffect(fxparams[0], fxparams[1]));
- break;
- case "distortion":
- addEffectForTag(p, new DistortionEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
- break;
- case "compressor":
- addEffectForTag(p, new CompressorEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
- break;
- case "analyser":
- addEffectForTag(p, new AnalyserEffect(fxparams[0], fxparams[1]));
- break;
- }
- }
- }
- }
- for (i = 0, len = playingarr.length; i < len; i++)
- {
- if (this.saveload === 3) // not saving/loading any sounds/music
- continue;
- d = playingarr[i];
- src = d["buffersrc"];
- is_music = d["is_music"];
- tag = d["tag"];
- playbackTime = d["playbackTime"];
- looping = d["looping"];
- vol = d["volume"];
- pan = d["pan"];
- panObjUid = (pan && pan.hasOwnProperty("objUid")) ? pan["objUid"] : -1;
- if (is_music && this.saveload === 1) // not saving/loading music
- continue;
- if (!is_music && this.saveload === 2) // not saving/loading sound
- continue;
- a = this.getAudioInstance(src, tag, is_music, looping, vol);
- if (!a)
- {
- b = this.getAudioBuffer(src, is_music);
- b.seekWhenReady = playbackTime;
- b.pauseWhenReady = d["paused"];
- if (pan)
- {
- if (panObjUid !== -1)
- {
- b.panWhenReady.push({ objUid: panObjUid, ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
- }
- else
- {
- b.panWhenReady.push({ x: pan["x"], y: pan["y"], a: pan["a"], ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
- }
- }
- continue;
- }
- a.resume_position = d["resume_position"];
- a.setPannerEnabled(!!pan);
- a.play(looping, vol, playbackTime);
- a.updatePlaybackRate();
- a.updateVolume();
- a.doSetMuted(a.is_muted || a.is_silent);
- if (d["paused"])
- a.pause();
- if (d["muted"])
- a.setMuted(true);
- a.doSetMuted(a.is_muted || a.is_silent);
- if (pan)
- {
- if (panObjUid !== -1)
- {
- a.objectTracker = a.objectTracker || new ObjectTracker();
- a.objectTracker.loadUid = panObjUid;
- objectTrackerUidsToLoad.push(a.objectTracker);
- }
- else
- {
- a.setPan(pan["x"], pan["y"], pan["a"], pan["ia"], pan["oa"], pan["og"]);
- }
- }
- }
- if (setSilent && !silent) // setting silent
- {
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].setSilent(true);
- silent = true;
- }
- else if (!setSilent && silent) // setting not silent
- {
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].setSilent(false);
- silent = false;
- }
- };
- instanceProto.afterLoad = function ()
- {
- var i, len, ot, inst;
- for (i = 0, len = objectTrackerUidsToLoad.length; i < len; i++)
- {
- ot = objectTrackerUidsToLoad[i];
- inst = this.runtime.getObjectByUID(ot.loadUid);
- ot.setObject(inst);
- ot.loadUid = -1;
- if (inst)
- {
- listenerX = inst.x;
- listenerY = inst.y;
- }
- }
- cr.clearArray(objectTrackerUidsToLoad);
- };
- instanceProto.onSuspend = function (s)
- {
- if (this.playinbackground)
- return;
- if (!s && context && context["resume"])
- {
- context["resume"]();
- isContextSuspended = false;
- }
- var i, len;
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].setSuspended(s);
- if (s && context && context["suspend"])
- {
- context["suspend"]();
- isContextSuspended = true;
- }
- };
- instanceProto.tick = function ()
- {
- var dt = this.runtime.dt;
- var i, len, a;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- a.tick(dt);
- if (timescale_mode !== 0)
- a.updatePlaybackRate();
- }
- var p, arr, f;
- for (p in effects)
- {
- if (effects.hasOwnProperty(p))
- {
- arr = effects[p];
- for (i = 0, len = arr.length; i < len; i++)
- {
- f = arr[i];
- if (f.tick)
- f.tick();
- }
- }
- }
- if (api === API_WEBAUDIO && this.listenerTracker.hasObject())
- {
- this.listenerTracker.tick(dt);
- listenerX = this.listenerTracker.obj.x;
- listenerY = this.listenerTracker.obj.y;
- context["listener"]["setPosition"](this.listenerTracker.obj.x, this.listenerTracker.obj.y, this.listenerZ);
- }
- };
- var preload_list = [];
- instanceProto.setPreloadList = function (arr)
- {
- var i, len, p, filename, size, isOgg;
- var total_size = 0;
- for (i = 0, len = arr.length; i < len; ++i)
- {
- p = arr[i];
- filename = p[0];
- size = p[1] * 2;
- isOgg = (filename.length > 4 && filename.substr(filename.length - 4) === ".ogg");
- if ((isOgg && useOgg) || (!isOgg && !useOgg))
- {
- preload_list.push({
- filename: filename,
- size: size,
- obj: null
- });
- total_size += size;
- }
- }
- return total_size;
- };
- instanceProto.startPreloads = function ()
- {
- var i, len, p, src;
- for (i = 0, len = preload_list.length; i < len; ++i)
- {
- p = preload_list[i];
- src = this.runtime.files_subfolder + p.filename;
- p.obj = this.getAudioBuffer(src, false);
- }
- };
- instanceProto.getPreloadedSize = function ()
- {
- var completed = 0;
- var i, len, p;
- for (i = 0, len = preload_list.length; i < len; ++i)
- {
- p = preload_list[i];
- if (p.obj.isLoadedAndDecoded() || p.obj.hasFailedToLoad() || this.runtime.isDomFree || this.runtime.isAndroidStockBrowser)
- {
- completed += p.size;
- }
- else if (p.obj.isLoaded()) // downloaded but not decoded: only happens in Web Audio API, count as half-way progress
- {
- completed += Math.floor(p.size / 2);
- }
- };
- return completed;
- };
- instanceProto.releaseAllMusicBuffers = function ()
- {
- var i, len, j, b;
- for (i = 0, j = 0, len = audioBuffers.length; i < len; ++i)
- {
- b = audioBuffers[i];
- audioBuffers[j] = b;
- if (b.is_music)
- b.release();
- else
- ++j; // keep
- }
- audioBuffers.length = j;
- };
- instanceProto.getAudioBuffer = function (src_, is_music, dont_create)
- {
- var i, len, a, ret = null, j, k, lenj, ai;
- for (i = 0, len = audioBuffers.length; i < len; i++)
- {
- a = audioBuffers[i];
- if (a.src === src_)
- {
- ret = a;
- break;
- }
- }
- if (!ret && !dont_create)
- {
- if (playMusicAsSoundWorkaround && is_music)
- this.releaseAllMusicBuffers();
- ret = new C2AudioBuffer(src_, is_music);
- audioBuffers.push(ret);
- }
- return ret;
- };
- instanceProto.getAudioInstance = function (src_, tag, is_music, looping, vol)
- {
- var i, len, a;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- if (a.src === src_ && (a.canBeRecycled() || is_music))
- {
- a.tag = tag;
- return a;
- }
- }
- var b = this.getAudioBuffer(src_, is_music);
- if (!b.bufferObject)
- {
- if (tag !== "")
- {
- b.playTagWhenReady = tag;
- b.loopWhenReady = looping;
- b.volumeWhenReady = vol;
- }
- return null;
- }
- a = new C2AudioInstance(b, tag);
- audioInstances.push(a);
- return a;
- };
- var taggedAudio = [];
- function SortByIsPlaying(a, b)
- {
- var an = a.isPlaying() ? 1 : 0;
- var bn = b.isPlaying() ? 1 : 0;
- if (an === bn)
- return 0;
- else if (an < bn)
- return 1;
- else
- return -1;
- };
- function getAudioByTag(tag, sort_by_playing)
- {
- cr.clearArray(taggedAudio);
- if (!tag.length)
- {
- if (!lastAudio || lastAudio.hasEnded())
- return;
- else
- {
- cr.clearArray(taggedAudio);
- taggedAudio[0] = lastAudio;
- return;
- }
- }
- var i, len, a;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- a = audioInstances[i];
- if (cr.equals_nocase(tag, a.tag))
- taggedAudio.push(a);
- }
- if (sort_by_playing)
- taggedAudio.sort(SortByIsPlaying);
- };
- function reconnectEffects(tag)
- {
- var i, len, arr, n, toNode = context["destination"];
- if (effects.hasOwnProperty(tag))
- {
- arr = effects[tag];
- if (arr.length)
- {
- toNode = arr[0].getInputNode();
- for (i = 0, len = arr.length; i < len; i++)
- {
- n = arr[i];
- if (i + 1 === len)
- n.connectTo(context["destination"]);
- else
- n.connectTo(arr[i + 1].getInputNode());
- }
- }
- }
- getAudioByTag(tag);
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].reconnect(toNode);
- if (micSource && micTag === tag)
- {
- micSource["disconnect"]();
- micSource["connect"](toNode);
- }
- };
- function addEffectForTag(tag, fx)
- {
- if (!effects.hasOwnProperty(tag))
- effects[tag] = [fx];
- else
- effects[tag].push(fx);
- reconnectEffects(tag);
- };
- function Cnds() {};
- Cnds.prototype.OnEnded = function (t)
- {
- return cr.equals_nocase(audTag, t);
- };
- Cnds.prototype.PreloadsComplete = function ()
- {
- var i, len;
- for (i = 0, len = audioBuffers.length; i < len; i++)
- {
- if (!audioBuffers[i].isLoadedAndDecoded() && !audioBuffers[i].hasFailedToLoad())
- return false;
- }
- return true;
- };
- Cnds.prototype.AdvancedAudioSupported = function ()
- {
- return api === API_WEBAUDIO;
- };
- Cnds.prototype.IsSilent = function ()
- {
- return silent;
- };
- Cnds.prototype.IsAnyPlaying = function ()
- {
- var i, len;
- for (i = 0, len = audioInstances.length; i < len; i++)
- {
- if (audioInstances[i].isPlaying())
- return true;
- }
- return false;
- };
- Cnds.prototype.IsTagPlaying = function (tag)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- {
- if (taggedAudio[i].isPlaying())
- return true;
- }
- return false;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.Play = function (file, looping, vol, tag)
- {
- if (silent)
- return;
- var v = dbToLinear(vol);
- var is_music = file[1];
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- return;
- lastAudio.setPannerEnabled(false);
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.PlayAtPosition = function (file, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
- {
- if (silent)
- return;
- var v = dbToLinear(vol);
- var is_music = file[1];
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- {
- var b = this.getAudioBuffer(src, is_music);
- b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
- return;
- }
- lastAudio.setPannerEnabled(true);
- lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.PlayAtObject = function (file, looping, vol, obj, innerangle, outerangle, outergain, tag)
- {
- if (silent || !obj)
- return;
- var inst = obj.getFirstPicked();
- if (!inst)
- return;
- var v = dbToLinear(vol);
- var is_music = file[1];
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- {
- var b = this.getAudioBuffer(src, is_music);
- b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
- return;
- }
- lastAudio.setPannerEnabled(true);
- var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
- var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
- lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
- lastAudio.setObject(inst);
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.PlayByName = function (folder, filename, looping, vol, tag)
- {
- if (silent)
- return;
- var v = dbToLinear(vol);
- var is_music = (folder === 1);
- var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- return;
- lastAudio.setPannerEnabled(false);
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.PlayAtPositionByName = function (folder, filename, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
- {
- if (silent)
- return;
- var v = dbToLinear(vol);
- var is_music = (folder === 1);
- var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- {
- var b = this.getAudioBuffer(src, is_music);
- b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
- return;
- }
- lastAudio.setPannerEnabled(true);
- lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.PlayAtObjectByName = function (folder, filename, looping, vol, obj, innerangle, outerangle, outergain, tag)
- {
- if (silent || !obj)
- return;
- var inst = obj.getFirstPicked();
- if (!inst)
- return;
- var v = dbToLinear(vol);
- var is_music = (folder === 1);
- var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
- lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
- if (!lastAudio)
- {
- var b = this.getAudioBuffer(src, is_music);
- b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
- return;
- }
- lastAudio.setPannerEnabled(true);
- var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
- var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
- lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
- lastAudio.setObject(inst);
- lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
- this.nextPlayTime = 0;
- };
- Acts.prototype.SetLooping = function (tag, looping)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].setLooping(looping === 0);
- };
- Acts.prototype.SetMuted = function (tag, muted)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].setMuted(muted === 0);
- };
- Acts.prototype.SetVolume = function (tag, vol)
- {
- getAudioByTag(tag);
- var v = dbToLinear(vol);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].setVolume(v);
- };
- Acts.prototype.Preload = function (file)
- {
- if (silent)
- return;
- var is_music = file[1];
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- if (api === API_APPMOBI)
- {
- if (this.runtime.isDirectCanvas)
- AppMobi["context"]["loadSound"](src);
- else
- AppMobi["player"]["loadSound"](src);
- return;
- }
- else if (api === API_CORDOVA)
- {
- return;
- }
- this.getAudioInstance(src, "", is_music, false);
- };
- Acts.prototype.PreloadByName = function (folder, filename)
- {
- if (silent)
- return;
- var is_music = (folder === 1);
- var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
- if (api === API_APPMOBI)
- {
- if (this.runtime.isDirectCanvas)
- AppMobi["context"]["loadSound"](src);
- else
- AppMobi["player"]["loadSound"](src);
- return;
- }
- else if (api === API_CORDOVA)
- {
- return;
- }
- this.getAudioInstance(src, "", is_music, false);
- };
- Acts.prototype.SetPlaybackRate = function (tag, rate)
- {
- getAudioByTag(tag);
- if (rate < 0.0)
- rate = 0;
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].setPlaybackRate(rate);
- };
- Acts.prototype.Stop = function (tag)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- taggedAudio[i].stop();
- };
- Acts.prototype.StopAll = function ()
- {
- var i, len;
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].stop();
- };
- Acts.prototype.SetPaused = function (tag, state)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- {
- if (state === 0)
- taggedAudio[i].pause();
- else
- taggedAudio[i].resume();
- }
- };
- Acts.prototype.Seek = function (tag, pos)
- {
- getAudioByTag(tag);
- var i, len;
- for (i = 0, len = taggedAudio.length; i < len; i++)
- {
- taggedAudio[i].seek(pos);
- }
- };
- Acts.prototype.SetSilent = function (s)
- {
- var i, len;
- if (s === 2) // toggling
- s = (silent ? 1 : 0); // choose opposite state
- if (s === 0 && !silent) // setting silent
- {
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].setSilent(true);
- silent = true;
- }
- else if (s === 1 && silent) // setting not silent
- {
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].setSilent(false);
- silent = false;
- }
- };
- Acts.prototype.SetMasterVolume = function (vol)
- {
- masterVolume = dbToLinear(vol);
- var i, len;
- for (i = 0, len = audioInstances.length; i < len; i++)
- audioInstances[i].updateVolume();
- };
- Acts.prototype.AddFilterEffect = function (tag, type, freq, detune, q, gain, mix)
- {
- if (api !== API_WEBAUDIO || type < 0 || type >= filterTypes.length || !context["createBiquadFilter"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new FilterEffect(type, freq, detune, q, gain, mix));
- };
- Acts.prototype.AddDelayEffect = function (tag, delay, gain, mix)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new DelayEffect(delay, dbToLinear(gain), mix));
- };
- Acts.prototype.AddFlangerEffect = function (tag, delay, modulation, freq, feedback, mix)
- {
- if (api !== API_WEBAUDIO || !context["createOscillator"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new FlangerEffect(delay / 1000, modulation / 1000, freq, feedback / 100, mix));
- };
- Acts.prototype.AddPhaserEffect = function (tag, freq, detune, q, mod, modfreq, mix)
- {
- if (api !== API_WEBAUDIO || !context["createOscillator"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new PhaserEffect(freq, detune, q, mod, modfreq, mix));
- };
- Acts.prototype.AddConvolutionEffect = function (tag, file, norm, mix)
- {
- if (api !== API_WEBAUDIO || !context["createConvolver"])
- return;
- var doNormalize = (norm === 0);
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- var b = this.getAudioBuffer(src, false);
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- var fx;
- if (b.bufferObject)
- {
- fx = new ConvolveEffect(b.bufferObject, doNormalize, mix, src);
- }
- else
- {
- fx = new ConvolveEffect(null, doNormalize, mix, src);
- b.normalizeWhenReady = doNormalize;
- b.convolveWhenReady = fx;
- }
- addEffectForTag(tag, fx);
- };
- Acts.prototype.AddGainEffect = function (tag, g)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- addEffectForTag(tag, new GainEffect(dbToLinear(g)));
- };
- Acts.prototype.AddMuteEffect = function (tag)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- addEffectForTag(tag, new GainEffect(0)); // re-use gain effect with 0 gain
- };
- Acts.prototype.AddTremoloEffect = function (tag, freq, mix)
- {
- if (api !== API_WEBAUDIO || !context["createOscillator"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new TremoloEffect(freq, mix));
- };
- Acts.prototype.AddRingModEffect = function (tag, freq, mix)
- {
- if (api !== API_WEBAUDIO || !context["createOscillator"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new RingModulatorEffect(freq, mix));
- };
- Acts.prototype.AddDistortionEffect = function (tag, threshold, headroom, drive, makeupgain, mix)
- {
- if (api !== API_WEBAUDIO || !context["createWaveShaper"])
- return;
- tag = tag.toLowerCase();
- mix = mix / 100;
- if (mix < 0) mix = 0;
- if (mix > 1) mix = 1;
- addEffectForTag(tag, new DistortionEffect(threshold, headroom, drive, makeupgain, mix));
- };
- Acts.prototype.AddCompressorEffect = function (tag, threshold, knee, ratio, attack, release)
- {
- if (api !== API_WEBAUDIO || !context["createDynamicsCompressor"])
- return;
- tag = tag.toLowerCase();
- addEffectForTag(tag, new CompressorEffect(threshold, knee, ratio, attack / 1000, release / 1000));
- };
- Acts.prototype.AddAnalyserEffect = function (tag, fftSize, smoothing)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- addEffectForTag(tag, new AnalyserEffect(fftSize, smoothing));
- };
- Acts.prototype.RemoveEffects = function (tag)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- var i, len, arr;
- if (effects.hasOwnProperty(tag))
- {
- arr = effects[tag];
- if (arr.length)
- {
- for (i = 0, len = arr.length; i < len; i++)
- arr[i].remove();
- cr.clearArray(arr);
- reconnectEffects(tag);
- }
- }
- };
- Acts.prototype.SetEffectParameter = function (tag, index, param, value, ramp, time)
- {
- if (api !== API_WEBAUDIO)
- return;
- tag = tag.toLowerCase();
- index = Math.floor(index);
- var arr;
- if (!effects.hasOwnProperty(tag))
- return;
- arr = effects[tag];
- if (index < 0 || index >= arr.length)
- return;
- arr[index].setParam(param, value, ramp, time);
- };
- Acts.prototype.SetListenerObject = function (obj_)
- {
- if (!obj_ || api !== API_WEBAUDIO)
- return;
- var inst = obj_.getFirstPicked();
- if (!inst)
- return;
- this.listenerTracker.setObject(inst);
- listenerX = inst.x;
- listenerY = inst.y;
- };
- Acts.prototype.SetListenerZ = function (z)
- {
- this.listenerZ = z;
- };
- Acts.prototype.ScheduleNextPlay = function (t)
- {
- if (!context)
- return; // needs Web Audio API
- this.nextPlayTime = t;
- };
- Acts.prototype.UnloadAudio = function (file)
- {
- var is_music = file[1];
- var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
- var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
- if (!b)
- return; // not loaded
- b.release();
- cr.arrayFindRemove(audioBuffers, b);
- };
- Acts.prototype.UnloadAudioByName = function (folder, filename)
- {
- var is_music = (folder === 1);
- var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
- var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
- if (!b)
- return; // not loaded
- b.release();
- cr.arrayFindRemove(audioBuffers, b);
- };
- Acts.prototype.UnloadAll = function ()
- {
- var i, len;
- for (i = 0, len = audioBuffers.length; i < len; ++i)
- {
- audioBuffers[i].release();
- };
- cr.clearArray(audioBuffers);
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.Duration = function (ret, tag)
- {
- getAudioByTag(tag, true);
- if (taggedAudio.length)
- ret.set_float(taggedAudio[0].getDuration());
- else
- ret.set_float(0);
- };
- Exps.prototype.PlaybackTime = function (ret, tag)
- {
- getAudioByTag(tag, true);
- if (taggedAudio.length)
- ret.set_float(taggedAudio[0].getPlaybackTime(true));
- else
- ret.set_float(0);
- };
- Exps.prototype.Volume = function (ret, tag)
- {
- getAudioByTag(tag, true);
- if (taggedAudio.length)
- {
- var v = taggedAudio[0].getVolume();
- ret.set_float(linearToDb(v));
- }
- else
- ret.set_float(0);
- };
- Exps.prototype.MasterVolume = function (ret)
- {
- ret.set_float(linearToDb(masterVolume));
- };
- Exps.prototype.EffectCount = function (ret, tag)
- {
- tag = tag.toLowerCase();
- var arr = null;
- if (effects.hasOwnProperty(tag))
- arr = effects[tag];
- ret.set_int(arr ? arr.length : 0);
- };
- function getAnalyser(tag, index)
- {
- var arr = null;
- if (effects.hasOwnProperty(tag))
- arr = effects[tag];
- if (arr && index >= 0 && index < arr.length && arr[index].freqBins)
- return arr[index];
- else
- return null;
- };
- Exps.prototype.AnalyserFreqBinCount = function (ret, tag, index)
- {
- tag = tag.toLowerCase();
- index = Math.floor(index);
- var analyser = getAnalyser(tag, index);
- ret.set_int(analyser ? analyser.node["frequencyBinCount"] : 0);
- };
- Exps.prototype.AnalyserFreqBinAt = function (ret, tag, index, bin)
- {
- tag = tag.toLowerCase();
- index = Math.floor(index);
- bin = Math.floor(bin);
- var analyser = getAnalyser(tag, index);
- if (!analyser)
- ret.set_float(0);
- else if (bin < 0 || bin >= analyser.node["frequencyBinCount"])
- ret.set_float(0);
- else
- ret.set_float(analyser.freqBins[bin]);
- };
- Exps.prototype.AnalyserPeakLevel = function (ret, tag, index)
- {
- tag = tag.toLowerCase();
- index = Math.floor(index);
- var analyser = getAnalyser(tag, index);
- if (analyser)
- ret.set_float(analyser.peak);
- else
- ret.set_float(0);
- };
- Exps.prototype.AnalyserRMSLevel = function (ret, tag, index)
- {
- tag = tag.toLowerCase();
- index = Math.floor(index);
- var analyser = getAnalyser(tag, index);
- if (analyser)
- ret.set_float(analyser.rms);
- else
- ret.set_float(0);
- };
- Exps.prototype.SampleRate = function (ret)
- {
- ret.set_int(context ? context.sampleRate : 0);
- };
- Exps.prototype.CurrentTime = function (ret)
- {
- ret.set_float(context ? context.currentTime : cr.performance_now());
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.Browser = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Browser.prototype;
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- };
- var offlineScriptReady = false;
- var browserPluginReady = false;
- document.addEventListener("DOMContentLoaded", function ()
- {
- if (window["C2_RegisterSW"] && navigator["serviceWorker"])
- {
- var offlineClientScript = document.createElement("script");
- offlineClientScript.onload = function ()
- {
- offlineScriptReady = true;
- checkReady()
- };
- offlineClientScript.src = "offlineClient.js";
- document.head.appendChild(offlineClientScript);
- }
- });
- var browserInstance = null;
- typeProto.onAppBegin = function ()
- {
- browserPluginReady = true;
- checkReady();
- };
- function checkReady()
- {
- if (offlineScriptReady && browserPluginReady && window["OfflineClientInfo"])
- {
- window["OfflineClientInfo"]["SetMessageCallback"](function (e)
- {
- browserInstance.onSWMessage(e);
- });
- }
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onCreate = function()
- {
- var self = this;
- window.addEventListener("resize", function () {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnResize, self);
- });
- browserInstance = this;
- if (typeof navigator.onLine !== "undefined")
- {
- window.addEventListener("online", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOnline, self);
- });
- window.addEventListener("offline", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOffline, self);
- });
- }
- if (!this.runtime.isDirectCanvas)
- {
- document.addEventListener("appMobi.device.update.available", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, self);
- });
- document.addEventListener("backbutton", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
- });
- document.addEventListener("menubutton", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
- });
- document.addEventListener("searchbutton", function() {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnSearchButton, self);
- });
- document.addEventListener("tizenhwkey", function (e) {
- var ret;
- switch (e["keyName"]) {
- case "back":
- ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
- if (!ret)
- {
- if (window["tizen"])
- window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
- }
- break;
- case "menu":
- ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
- if (!ret)
- e.preventDefault();
- break;
- }
- });
- }
- if (this.runtime.isWindows10 && typeof Windows !== "undefined")
- {
- Windows["UI"]["Core"]["SystemNavigationManager"]["getForCurrentView"]().addEventListener("backrequested", function (e)
- {
- var ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
- if (ret)
- e["handled"] = true;
- });
- }
- else if (this.runtime.isWinJS && WinJS["Application"])
- {
- WinJS["Application"]["onbackclick"] = function (e)
- {
- return !!self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
- };
- }
- this.runtime.addSuspendCallback(function(s) {
- if (s)
- {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageHidden, self);
- }
- else
- {
- self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageVisible, self);
- }
- });
- this.is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
- };
- instanceProto.onSWMessage = function (e)
- {
- var messageType = e["data"]["type"];
- if (messageType === "downloading-update")
- this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateFound, this);
- else if (messageType === "update-ready" || messageType === "update-pending")
- this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, this);
- else if (messageType === "offline-ready")
- this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOfflineReady, this);
- };
- var batteryManager = null;
- var loadedBatteryManager = false;
- function maybeLoadBatteryManager()
- {
- if (loadedBatteryManager)
- return;
- if (!navigator["getBattery"])
- return;
- var promise = navigator["getBattery"]();
- loadedBatteryManager = true;
- if (promise)
- {
- promise.then(function (manager) {
- batteryManager = manager;
- });
- }
- };
- function Cnds() {};
- Cnds.prototype.CookiesEnabled = function()
- {
- return navigator ? navigator.cookieEnabled : false;
- };
- Cnds.prototype.IsOnline = function()
- {
- return navigator ? navigator.onLine : false;
- };
- Cnds.prototype.HasJava = function()
- {
- return navigator ? navigator.javaEnabled() : false;
- };
- Cnds.prototype.OnOnline = function()
- {
- return true;
- };
- Cnds.prototype.OnOffline = function()
- {
- return true;
- };
- Cnds.prototype.IsDownloadingUpdate = function ()
- {
- return false; // deprecated
- };
- Cnds.prototype.OnUpdateReady = function ()
- {
- return true;
- };
- Cnds.prototype.PageVisible = function ()
- {
- return !this.runtime.isSuspended;
- };
- Cnds.prototype.OnPageVisible = function ()
- {
- return true;
- };
- Cnds.prototype.OnPageHidden = function ()
- {
- return true;
- };
- Cnds.prototype.OnResize = function ()
- {
- return true;
- };
- Cnds.prototype.IsFullscreen = function ()
- {
- return !!(document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
- };
- Cnds.prototype.OnBackButton = function ()
- {
- return true;
- };
- Cnds.prototype.OnMenuButton = function ()
- {
- return true;
- };
- Cnds.prototype.OnSearchButton = function ()
- {
- return true;
- };
- Cnds.prototype.IsMetered = function ()
- {
- var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
- if (!connection)
- return false;
- return !!connection["metered"];
- };
- Cnds.prototype.IsCharging = function ()
- {
- var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
- if (battery)
- {
- return !!battery["charging"]
- }
- else
- {
- maybeLoadBatteryManager();
- if (batteryManager)
- {
- return !!batteryManager["charging"];
- }
- else
- {
- return true; // if unknown, default to charging (powered)
- }
- }
- };
- Cnds.prototype.IsPortraitLandscape = function (p)
- {
- var current = (window.innerWidth <= window.innerHeight ? 0 : 1);
- return current === p;
- };
- Cnds.prototype.SupportsFullscreen = function ()
- {
- if (this.runtime.isNodeWebkit)
- return true;
- var elem = this.runtime.canvasdiv || this.runtime.canvas;
- return !!(elem["requestFullscreen"] || elem["mozRequestFullScreen"] || elem["msRequestFullscreen"] || elem["webkitRequestFullScreen"]);
- };
- Cnds.prototype.OnUpdateFound = function ()
- {
- return true;
- };
- Cnds.prototype.OnUpdateReady = function ()
- {
- return true;
- };
- Cnds.prototype.OnOfflineReady = function ()
- {
- return true;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.Alert = function (msg)
- {
- if (!this.runtime.isDomFree)
- alert(msg.toString());
- };
- Acts.prototype.Close = function ()
- {
- if (this.runtime.isCocoonJs)
- CocoonJS["App"]["forceToFinish"]();
- else if (window["tizen"])
- window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
- else if (navigator["app"] && navigator["app"]["exitApp"])
- navigator["app"]["exitApp"]();
- else if (navigator["device"] && navigator["device"]["exitApp"])
- navigator["device"]["exitApp"]();
- else if (!this.is_arcade && !this.runtime.isDomFree)
- window.close();
- };
- Acts.prototype.Focus = function ()
- {
- if (this.runtime.isNodeWebkit)
- {
- var win = window["nwgui"]["Window"]["get"]();
- win["focus"]();
- }
- else if (!this.is_arcade && !this.runtime.isDomFree)
- window.focus();
- };
- Acts.prototype.Blur = function ()
- {
- if (this.runtime.isNodeWebkit)
- {
- var win = window["nwgui"]["Window"]["get"]();
- win["blur"]();
- }
- else if (!this.is_arcade && !this.runtime.isDomFree)
- window.blur();
- };
- Acts.prototype.GoBack = function ()
- {
- if (navigator["app"] && navigator["app"]["backHistory"])
- navigator["app"]["backHistory"]();
- else if (!this.is_arcade && !this.runtime.isDomFree && window.back)
- window.back();
- };
- Acts.prototype.GoForward = function ()
- {
- if (!this.is_arcade && !this.runtime.isDomFree && window.forward)
- window.forward();
- };
- Acts.prototype.GoHome = function ()
- {
- if (!this.is_arcade && !this.runtime.isDomFree && window.home)
- window.home();
- };
- Acts.prototype.GoToURL = function (url, target)
- {
- if (this.runtime.isCocoonJs)
- CocoonJS["App"]["openURL"](url);
- else if (this.runtime.isEjecta)
- ejecta["openURL"](url);
- else if (this.runtime.isWinJS)
- Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
- else if (navigator["app"] && navigator["app"]["loadUrl"])
- navigator["app"]["loadUrl"](url, { "openExternal": true });
- else if (self["cordova"] && self["cordova"]["InAppBrowser"])
- self["cordova"]["InAppBrowser"]["open"](url, "_system");
- else if (!this.is_arcade && !this.runtime.isDomFree)
- {
- if (target === 2 && !this.is_arcade) // top
- window.top.location = url;
- else if (target === 1 && !this.is_arcade) // parent
- window.parent.location = url;
- else // self
- window.location = url;
- }
- };
- Acts.prototype.GoToURLWindow = function (url, tag)
- {
- if (this.runtime.isCocoonJs)
- CocoonJS["App"]["openURL"](url);
- else if (this.runtime.isEjecta)
- ejecta["openURL"](url);
- else if (this.runtime.isWinJS)
- Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
- else if (navigator["app"] && navigator["app"]["loadUrl"])
- navigator["app"]["loadUrl"](url, { "openExternal": true });
- else if (self["cordova"] && self["cordova"]["InAppBrowser"])
- self["cordova"]["InAppBrowser"]["open"](url, "_system");
- else if (!this.is_arcade && !this.runtime.isDomFree)
- window.open(url, tag);
- };
- Acts.prototype.Reload = function ()
- {
- if (!this.is_arcade && !this.runtime.isDomFree)
- window.location.reload();
- };
- var firstRequestFullscreen = true;
- var crruntime = null;
- function onFullscreenError(e)
- {
- if (console && console.warn)
- console.warn("Fullscreen request failed: ", e);
- crruntime["setSize"](window.innerWidth, window.innerHeight);
- };
- Acts.prototype.RequestFullScreen = function (stretchmode)
- {
- if (this.runtime.isDomFree)
- {
- cr.logexport("[Construct 2] Requesting fullscreen is not supported on this platform - the request has been ignored");
- return;
- }
- if (stretchmode >= 2)
- stretchmode += 1;
- if (stretchmode === 6)
- stretchmode = 2;
- if (this.runtime.isNodeWebkit)
- {
- if (this.runtime.isDebug)
- {
- debuggerFullscreen(true);
- }
- else if (!this.runtime.isNodeFullscreen && window["nwgui"])
- {
- window["nwgui"]["Window"]["get"]()["enterFullscreen"]();
- this.runtime.isNodeFullscreen = true;
- this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
- }
- }
- else
- {
- if (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || document["fullScreenElement"])
- {
- return;
- }
- this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
- var elem = document.documentElement;
- if (firstRequestFullscreen)
- {
- firstRequestFullscreen = false;
- crruntime = this.runtime;
- elem.addEventListener("mozfullscreenerror", onFullscreenError);
- elem.addEventListener("webkitfullscreenerror", onFullscreenError);
- elem.addEventListener("MSFullscreenError", onFullscreenError);
- elem.addEventListener("fullscreenerror", onFullscreenError);
- }
- if (elem["requestFullscreen"])
- elem["requestFullscreen"]();
- else if (elem["mozRequestFullScreen"])
- elem["mozRequestFullScreen"]();
- else if (elem["msRequestFullscreen"])
- elem["msRequestFullscreen"]();
- else if (elem["webkitRequestFullScreen"])
- {
- if (typeof Element !== "undefined" && typeof Element["ALLOW_KEYBOARD_INPUT"] !== "undefined")
- elem["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]);
- else
- elem["webkitRequestFullScreen"]();
- }
- }
- };
- Acts.prototype.CancelFullScreen = function ()
- {
- if (this.runtime.isDomFree)
- {
- cr.logexport("[Construct 2] Exiting fullscreen is not supported on this platform - the request has been ignored");
- return;
- }
- if (this.runtime.isNodeWebkit)
- {
- if (this.runtime.isDebug)
- {
- debuggerFullscreen(false);
- }
- else if (this.runtime.isNodeFullscreen && window["nwgui"])
- {
- window["nwgui"]["Window"]["get"]()["leaveFullscreen"]();
- this.runtime.isNodeFullscreen = false;
- }
- }
- else
- {
- if (document["exitFullscreen"])
- document["exitFullscreen"]();
- else if (document["mozCancelFullScreen"])
- document["mozCancelFullScreen"]();
- else if (document["msExitFullscreen"])
- document["msExitFullscreen"]();
- else if (document["webkitCancelFullScreen"])
- document["webkitCancelFullScreen"]();
- }
- };
- Acts.prototype.Vibrate = function (pattern_)
- {
- try {
- var arr = pattern_.split(",");
- var i, len;
- for (i = 0, len = arr.length; i < len; i++)
- {
- arr[i] = parseInt(arr[i], 10);
- }
- if (navigator["vibrate"])
- navigator["vibrate"](arr);
- else if (navigator["mozVibrate"])
- navigator["mozVibrate"](arr);
- else if (navigator["webkitVibrate"])
- navigator["webkitVibrate"](arr);
- else if (navigator["msVibrate"])
- navigator["msVibrate"](arr);
- }
- catch (e) {}
- };
- Acts.prototype.InvokeDownload = function (url_, filename_)
- {
- var a = document.createElement("a");
- if (typeof a["download"] === "undefined")
- {
- window.open(url_);
- }
- else
- {
- var body = document.getElementsByTagName("body")[0];
- a.textContent = filename_;
- a.href = url_;
- a["download"] = filename_;
- body.appendChild(a);
- var clickEvent = new MouseEvent("click");
- a.dispatchEvent(clickEvent);
- body.removeChild(a);
- }
- };
- Acts.prototype.InvokeDownloadString = function (str_, mimetype_, filename_)
- {
- var datauri = "data:" + mimetype_ + "," + encodeURIComponent(str_);
- var a = document.createElement("a");
- if (typeof a["download"] === "undefined")
- {
- window.open(datauri);
- }
- else
- {
- var body = document.getElementsByTagName("body")[0];
- a.textContent = filename_;
- a.href = datauri;
- a["download"] = filename_;
- body.appendChild(a);
- var clickEvent = new MouseEvent("click");
- a.dispatchEvent(clickEvent);
- body.removeChild(a);
- }
- };
- Acts.prototype.ConsoleLog = function (type_, msg_)
- {
- if (typeof console === "undefined")
- return;
- if (type_ === 0 && console.log)
- console.log(msg_.toString());
- if (type_ === 1 && console.warn)
- console.warn(msg_.toString());
- if (type_ === 2 && console.error)
- console.error(msg_.toString());
- };
- Acts.prototype.ConsoleGroup = function (name_)
- {
- if (console && console.group)
- console.group(name_);
- };
- Acts.prototype.ConsoleGroupEnd = function ()
- {
- if (console && console.groupEnd)
- console.groupEnd();
- };
- Acts.prototype.ExecJs = function (js_)
- {
- try {
- if (eval)
- eval(js_);
- }
- catch (e)
- {
- if (console && console.error)
- console.error("Error executing Javascript: ", e);
- }
- };
- var orientations = [
- "portrait",
- "landscape",
- "portrait-primary",
- "portrait-secondary",
- "landscape-primary",
- "landscape-secondary"
- ];
- Acts.prototype.LockOrientation = function (o)
- {
- o = Math.floor(o);
- if (o < 0 || o >= orientations.length)
- return;
- this.runtime.autoLockOrientation = false;
- var orientation = orientations[o];
- if (screen["orientation"] && screen["orientation"]["lock"])
- screen["orientation"]["lock"](orientation);
- else if (screen["lockOrientation"])
- screen["lockOrientation"](orientation);
- else if (screen["webkitLockOrientation"])
- screen["webkitLockOrientation"](orientation);
- else if (screen["mozLockOrientation"])
- screen["mozLockOrientation"](orientation);
- else if (screen["msLockOrientation"])
- screen["msLockOrientation"](orientation);
- };
- Acts.prototype.UnlockOrientation = function ()
- {
- this.runtime.autoLockOrientation = false;
- if (screen["orientation"] && screen["orientation"]["unlock"])
- screen["orientation"]["unlock"]();
- else if (screen["unlockOrientation"])
- screen["unlockOrientation"]();
- else if (screen["webkitUnlockOrientation"])
- screen["webkitUnlockOrientation"]();
- else if (screen["mozUnlockOrientation"])
- screen["mozUnlockOrientation"]();
- else if (screen["msUnlockOrientation"])
- screen["msUnlockOrientation"]();
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.URL = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.toString());
- };
- Exps.prototype.Protocol = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.protocol);
- };
- Exps.prototype.Domain = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.hostname);
- };
- Exps.prototype.PathName = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.pathname);
- };
- Exps.prototype.Hash = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.hash);
- };
- Exps.prototype.Referrer = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : document.referrer);
- };
- Exps.prototype.Title = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : document.title);
- };
- Exps.prototype.Name = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : navigator.appName);
- };
- Exps.prototype.Version = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : navigator.appVersion);
- };
- Exps.prototype.Language = function (ret)
- {
- if (navigator && navigator.language)
- ret.set_string(navigator.language);
- else
- ret.set_string("");
- };
- Exps.prototype.Platform = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : navigator.platform);
- };
- Exps.prototype.Product = function (ret)
- {
- if (navigator && navigator.product)
- ret.set_string(navigator.product);
- else
- ret.set_string("");
- };
- Exps.prototype.Vendor = function (ret)
- {
- if (navigator && navigator.vendor)
- ret.set_string(navigator.vendor);
- else
- ret.set_string("");
- };
- Exps.prototype.UserAgent = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : navigator.userAgent);
- };
- Exps.prototype.QueryString = function (ret)
- {
- ret.set_string(this.runtime.isDomFree ? "" : window.location.search);
- };
- Exps.prototype.QueryParam = function (ret, paramname)
- {
- if (this.runtime.isDomFree)
- {
- ret.set_string("");
- return;
- }
- var match = RegExp('[?&]' + paramname + '=([^&]*)').exec(window.location.search);
- if (match)
- ret.set_string(decodeURIComponent(match[1].replace(/\+/g, ' ')));
- else
- ret.set_string("");
- };
- Exps.prototype.Bandwidth = function (ret)
- {
- var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
- if (!connection)
- ret.set_float(Number.POSITIVE_INFINITY);
- else
- {
- if (typeof connection["bandwidth"] !== "undefined")
- ret.set_float(connection["bandwidth"]);
- else if (typeof connection["downlinkMax"] !== "undefined")
- ret.set_float(connection["downlinkMax"]);
- else
- ret.set_float(Number.POSITIVE_INFINITY);
- }
- };
- Exps.prototype.ConnectionType = function (ret)
- {
- var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
- if (!connection)
- ret.set_string("unknown");
- else
- {
- ret.set_string(connection["type"] || "unknown");
- }
- };
- Exps.prototype.BatteryLevel = function (ret)
- {
- var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
- if (battery)
- {
- ret.set_float(battery["level"]);
- }
- else
- {
- maybeLoadBatteryManager();
- if (batteryManager)
- {
- ret.set_float(batteryManager["level"]);
- }
- else
- {
- ret.set_float(1); // not supported/unknown: assume charged
- }
- }
- };
- Exps.prototype.BatteryTimeLeft = function (ret)
- {
- var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
- if (battery)
- {
- ret.set_float(battery["dischargingTime"]);
- }
- else
- {
- maybeLoadBatteryManager();
- if (batteryManager)
- {
- ret.set_float(batteryManager["dischargingTime"]);
- }
- else
- {
- ret.set_float(Number.POSITIVE_INFINITY); // not supported/unknown: assume infinite time left
- }
- }
- };
- Exps.prototype.ExecJS = function (ret, js_)
- {
- if (!eval)
- {
- ret.set_any(0);
- return;
- }
- var result = 0;
- try {
- result = eval(js_);
- }
- catch (e)
- {
- if (console && console.error)
- console.error("Error executing Javascript: ", e);
- }
- if (typeof result === "number")
- ret.set_any(result);
- else if (typeof result === "string")
- ret.set_any(result);
- else if (typeof result === "boolean")
- ret.set_any(result ? 1 : 0);
- else
- ret.set_any(0);
- };
- Exps.prototype.ScreenWidth = function (ret)
- {
- ret.set_int(screen.width);
- };
- Exps.prototype.ScreenHeight = function (ret)
- {
- ret.set_int(screen.height);
- };
- Exps.prototype.DevicePixelRatio = function (ret)
- {
- ret.set_float(this.runtime.devicePixelRatio);
- };
- Exps.prototype.WindowInnerWidth = function (ret)
- {
- ret.set_int(window.innerWidth);
- };
- Exps.prototype.WindowInnerHeight = function (ret)
- {
- ret.set_int(window.innerHeight);
- };
- Exps.prototype.WindowOuterWidth = function (ret)
- {
- ret.set_int(window.outerWidth);
- };
- Exps.prototype.WindowOuterHeight = function (ret)
- {
- ret.set_int(window.outerHeight);
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.Function = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Function.prototype;
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- };
- var instanceProto = pluginProto.Instance.prototype;
- var funcStack = [];
- var funcStackPtr = -1;
- var isInPreview = false; // set in onCreate
- function FuncStackEntry()
- {
- this.name = "";
- this.retVal = 0;
- this.params = [];
- };
- function pushFuncStack()
- {
- funcStackPtr++;
- if (funcStackPtr === funcStack.length)
- funcStack.push(new FuncStackEntry());
- return funcStack[funcStackPtr];
- };
- function getCurrentFuncStack()
- {
- if (funcStackPtr < 0)
- return null;
- return funcStack[funcStackPtr];
- };
- function getOneAboveFuncStack()
- {
- if (!funcStack.length)
- return null;
- var i = funcStackPtr + 1;
- if (i >= funcStack.length)
- i = funcStack.length - 1;
- return funcStack[i];
- };
- function popFuncStack()
- {
-;
- funcStackPtr--;
- };
- instanceProto.onCreate = function()
- {
- isInPreview = (typeof cr_is_preview !== "undefined");
- var self = this;
- window["c2_callFunction"] = function (name_, params_)
- {
- var i, len, v;
- var fs = pushFuncStack();
- fs.name = name_.toLowerCase();
- fs.retVal = 0;
- if (params_)
- {
- fs.params.length = params_.length;
- for (i = 0, len = params_.length; i < len; ++i)
- {
- v = params_[i];
- if (typeof v === "number" || typeof v === "string")
- fs.params[i] = v;
- else if (typeof v === "boolean")
- fs.params[i] = (v ? 1 : 0);
- else
- fs.params[i] = 0;
- }
- }
- else
- {
- cr.clearArray(fs.params);
- }
- self.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, self, fs.name);
- popFuncStack();
- return fs.retVal;
- };
- };
- function Cnds() {};
- Cnds.prototype.OnFunction = function (name_)
- {
- var fs = getCurrentFuncStack();
- if (!fs)
- return false;
- return cr.equals_nocase(name_, fs.name);
- };
- Cnds.prototype.CompareParam = function (index_, cmp_, value_)
- {
- var fs = getCurrentFuncStack();
- if (!fs)
- return false;
- index_ = cr.floor(index_);
- if (index_ < 0 || index_ >= fs.params.length)
- return false;
- return cr.do_cmp(fs.params[index_], cmp_, value_);
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.CallFunction = function (name_, params_)
- {
- var fs = pushFuncStack();
- fs.name = name_.toLowerCase();
- fs.retVal = 0;
- cr.shallowAssignArray(fs.params, params_);
- var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
- if (isInPreview && !ran)
- {
-;
- }
- popFuncStack();
- };
- Acts.prototype.SetReturnValue = function (value_)
- {
- var fs = getCurrentFuncStack();
- if (fs)
- fs.retVal = value_;
- else
-;
- };
- Acts.prototype.CallExpression = function (unused)
- {
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.ReturnValue = function (ret)
- {
- var fs = getOneAboveFuncStack();
- if (fs)
- ret.set_any(fs.retVal);
- else
- ret.set_int(0);
- };
- Exps.prototype.ParamCount = function (ret)
- {
- var fs = getCurrentFuncStack();
- if (fs)
- ret.set_int(fs.params.length);
- else
- {
-;
- ret.set_int(0);
- }
- };
- Exps.prototype.Param = function (ret, index_)
- {
- index_ = cr.floor(index_);
- var fs = getCurrentFuncStack();
- if (fs)
- {
- if (index_ >= 0 && index_ < fs.params.length)
- {
- ret.set_any(fs.params[index_]);
- }
- else
- {
-;
- ret.set_int(0);
- }
- }
- else
- {
-;
- ret.set_int(0);
- }
- };
- Exps.prototype.Call = function (ret, name_)
- {
- var fs = pushFuncStack();
- fs.name = name_.toLowerCase();
- fs.retVal = 0;
- cr.clearArray(fs.params);
- var i, len;
- for (i = 2, len = arguments.length; i < len; i++)
- fs.params.push(arguments[i]);
- var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
- if (isInPreview && !ran)
- {
-;
- }
- popFuncStack();
- ret.set_any(fs.retVal);
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.SenaPlugin = function (runtime) {
- this.runtime = runtime;
-};
-(function () {
- var pluginProto = cr.plugins_.SenaPlugin.prototype;
- pluginProto.Type = function (plugin) {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function () {
- };
- pluginProto.Instance = function (type) {
- this.type = type;
- this.runtime = type.runtime;
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onCreate = function () {
- window['SenaTrigger'] = this;
- this.sdk = null;
- this.isPaused = false;
- this.pauseTime = 0;
- this.totalPausedTime = 0;
- this.bgMusic = null;
- this.bgMusicPlaying = false;
- this.bgMusicPaused = false;
- this.calculatedPositions = [];
- };
- instanceProto.onDestroy = function () {
- if (this.sdk) {
- this.sdk.destroy();
- }
- if (this.bgMusic) {
- this.bgMusic.pause();
- this.bgMusic = null;
- }
- };
- function Cnds() {
- };
- Cnds.prototype.OnLoad = function () {
- return true;
- };
- Cnds.prototype.OnStart = function () {
- return true;
- };
- Cnds.prototype.OnCorrect = function () {
- return true;
- };
- Cnds.prototype.OnWrong = function () {
- return true;
- };
- Cnds.prototype.OnPause = function () {
- return true;
- };
- Cnds.prototype.OnResume = function () {
- return true;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {
- };
- Acts.prototype.Load = function () {
- var self = this;
- var gameCode = this.properties[0] || 'G2510S1T30';
- if (window['SenaSDK']) {
- this.sdk = new window['SenaSDK'](gameCode);
- this.sdk.load(function(success) {
- if (success) {
- console.log('SDK loaded successfully');
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnLoad, window['SenaTrigger']);
- } else {
- console.error('Failed to load SDK data');
- }
- }, gameCode);
- } else {
- console.error('SenaSDK not found');
- }
- };
- Acts.prototype.Start = function () {
- var self = this;
- if (self.sdk) {
- self.sdk.start();
- console.log('Game started');
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnStart, window['SenaTrigger']);
- }
- };
- Acts.prototype.Finish = function (answer) {
- var self = this;
- if (this.sdk) {
- this.sdk.end(answer, function(isCorrect) {
- if (isCorrect) {
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnCorrect, window['SenaTrigger']);
- } else {
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnWrong, window['SenaTrigger']);
- }
- });
- }
- };
- Acts.prototype.PlayVoice = function (type) {
- var self = this;
- if (this.sdk && this.sdk.playVoice) {
- this.sdk.playVoice(type);
- }
- };
- Acts.prototype.StopVoice = function () {
- var self = this;
- if (this.sdk && this.sdk.stopSound) {
- this.sdk.stopSound();
- }
- };
- Acts.prototype.PlayBGMusic = function () {
- var self = this;
- if (this.bgMusic) {
- this.bgMusic.play();
- this.bgMusicPlaying = true;
- this.bgMusicPaused = false;
- }
- };
- Acts.prototype.StopBGMusic = function () {
- var self = this;
- if (this.bgMusic) {
- this.bgMusic.pause();
- this.bgMusic.currentTime = 0;
- this.bgMusicPlaying = false;
- this.bgMusicPaused = false;
- }
- };
- Acts.prototype.PauseBGMusic = function () {
- var self = this;
- if (this.bgMusic && this.bgMusicPlaying) {
- this.bgMusic.pause();
- this.bgMusicPaused = true;
- }
- };
- Acts.prototype.ResumeBGMusic = function () {
- var self = this;
- if (this.bgMusic && this.bgMusicPaused) {
- this.bgMusic.play();
- this.bgMusicPaused = false;
- }
- };
- Acts.prototype.PauseGame = function () {
- var self = this;
- if (!this.isPaused) {
- this.isPaused = true;
- this.pauseTime = Date.now();
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnPause, window['SenaTrigger']);
- }
- };
- Acts.prototype.ResumeGame = function () {
- var self = this;
- if (this.isPaused) {
- this.isPaused = false;
- this.totalPausedTime += (Date.now() - this.pauseTime);
- window['SenaTrigger'].runtime.trigger(cr.plugins_.SenaPlugin.prototype.cnds.OnResume, window['SenaTrigger']);
- }
- };
- Acts.prototype.ResetGame = function () {
- var self = this;
- if (this.sdk && this.sdk.reset) {
- this.sdk.reset();
- this.isPaused = false;
- this.pauseTime = 0;
- this.totalPausedTime = 0;
- }
- };
- Acts.prototype.CalcObjectPositions = function (
- count,
- objectWidth,
- margin,
- maxWidth,
- rowBreak,
- rowGap,
- type
-) {
- this.calculatedPositions = [];
- if (count <= 0) return;
- var rows = [];
- if (rowBreak > 0) {
- for (var i = 0; i < count; i += rowBreak) {
- rows.push(Math.min(rowBreak, count - i));
- }
- } else {
- if (count <= 5) {
- rows.push(count);
- } else {
- var top = Math.ceil((count + 1) / 2);
- var bottom = count - top;
- rows.push(top);
- rows.push(bottom);
- }
- }
- var baseY = 0;
- if (type === "word") {
- baseY = rowGap * rows.length; // word luôn nằm dưới slot
- }
- var index = 0;
- for (var r = 0; r < rows.length; r++) {
- var itemsInRow = rows[r];
- var rowWidth = itemsInRow * objectWidth + (itemsInRow - 1) * margin;
- var startX = (maxWidth - rowWidth) / 2;
- for (var i = 0; i < itemsInRow; i++) {
- this.calculatedPositions.push({
- x: startX + i * (objectWidth + margin) + objectWidth / 2,
- y: baseY + r * rowGap
- });
- index++;
- }
- }
-};
- pluginProto.acts = new Acts();
- function Exps() {
- };
- Exps.prototype.getQuestionValue = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getQuestionValue() || "");
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getQuestionType = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getQuestionType() || "text");
- } else {
- ret.set_string("text");
- }
- };
- Exps.prototype.getRequestValue = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getRequestValue() || "");
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getRequestType = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getRequestType() || "text");
- } else {
- ret.set_string("text");
- }
- };
- Exps.prototype.getOptionsCount = function (ret) {
- if (this.sdk) {
- ret.set_int(this.sdk.getOptionsCount() || 0);
- } else {
- ret.set_int(0);
- }
- };
- Exps.prototype.getOptionsType = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getOptionsType() || "text");
- } else {
- ret.set_string("text");
- }
- };
- Exps.prototype.getOptionsValue = function (ret, index) {
- if (this.sdk) {
- var value = this.sdk.getOptionsValue(index);
- if (value && typeof value === 'object') {
- ret.set_string(JSON.stringify(value));
- } else {
- ret.set_string(value || "");
- }
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getHintType = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.getHintType() || "");
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getHintCount = function (ret) {
- if (this.sdk) {
- ret.set_int(this.sdk.getHintCount() || 0);
- } else {
- ret.set_int(0);
- }
- };
- Exps.prototype.getHintValue = function (ret, index) {
- if (this.sdk) {
- var value = this.sdk.getHintValue(index);
- if (value === null) {
- ret.set_string("");
- } else if (typeof value === 'object') {
- ret.set_string(JSON.stringify(value));
- } else {
- ret.set_string(value.toString());
- }
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getTimeLimit = function (ret) {
- if (this.sdk) {
- ret.set_int(this.sdk.timeLimit || 0);
- } else {
- ret.set_int(0);
- }
- };
- Exps.prototype.getShuffle = function (ret) {
- if (this.sdk) {
- ret.set_int(this.sdk.shuffle ? 1 : 0);
- } else {
- ret.set_int(1);
- }
- };
- Exps.prototype.getGameCode = function (ret) {
- if (this.sdk) {
- ret.set_string(this.sdk.gameCode || "");
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.getGuide = function (ret) {
- if (this.sdk && this.sdk.guide) {
- ret.set_string(this.sdk.guide() || "");
- } else {
- ret.set_string("");
- }
- };
- Exps.prototype.isVoicePlaying = function (ret) {
- if (this.sdk && this.sdk.isSpeaking) {
- ret.set_int(this.sdk.isSpeaking() ? 1 : 0);
- } else {
- ret.set_int(0);
- }
- };
- Exps.prototype.isMusicPlaying = function (ret) {
- ret.set_int(this.bgMusicPlaying ? 1 : 0);
- };
- Exps.prototype.isMusicPaused = function (ret) {
- ret.set_int(this.bgMusicPaused ? 1 : 0);
- };
- Exps.prototype.isGamePaused = function (ret) {
- ret.set_int(this.isPaused ? 1 : 0);
- };
- Exps.prototype.getElapsedTime = function (ret) {
- if (this.sdk && this.sdk.startTime) {
- var elapsed = (Date.now() - this.sdk.startTime - this.totalPausedTime) / 1000;
- if (this.isPaused) {
- elapsed -= (Date.now() - this.pauseTime) / 1000;
- }
- ret.set_float(Math.max(0, elapsed));
- } else {
- ret.set_float(0);
- }
- };
- Exps.prototype.getPosXbyIndex = function (ret, index) {
- if (this.calculatedPositions[index]) {
- ret.set_float(this.calculatedPositions[index].x);
- } else {
- ret.set_float(0);
- }
-};
-Exps.prototype.getPosYbyIndex = function (ret, index) {
- if (this.calculatedPositions[index]) {
- ret.set_float(this.calculatedPositions[index].y);
- } else {
- ret.set_float(0);
- }
-};
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.Sprite = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Sprite.prototype;
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- function frame_getDataUri()
- {
- if (this.datauri.length === 0)
- {
- var tmpcanvas = document.createElement("canvas");
- tmpcanvas.width = this.width;
- tmpcanvas.height = this.height;
- var tmpctx = tmpcanvas.getContext("2d");
- if (this.spritesheeted)
- {
- tmpctx.drawImage(this.texture_img, this.offx, this.offy, this.width, this.height,
- 0, 0, this.width, this.height);
- }
- else
- {
- tmpctx.drawImage(this.texture_img, 0, 0, this.width, this.height);
- }
- this.datauri = tmpcanvas.toDataURL("image/png");
- }
- return this.datauri;
- };
- typeProto.onCreate = function()
- {
- if (this.is_family)
- return;
- var i, leni, j, lenj;
- var anim, frame, animobj, frameobj, wt, uv;
- this.all_frames = [];
- this.has_loaded_textures = false;
- for (i = 0, leni = this.animations.length; i < leni; i++)
- {
- anim = this.animations[i];
- animobj = {};
- animobj.name = anim[0];
- animobj.speed = anim[1];
- animobj.loop = anim[2];
- animobj.repeatcount = anim[3];
- animobj.repeatto = anim[4];
- animobj.pingpong = anim[5];
- animobj.sid = anim[6];
- animobj.frames = [];
- for (j = 0, lenj = anim[7].length; j < lenj; j++)
- {
- frame = anim[7][j];
- frameobj = {};
- frameobj.texture_file = frame[0];
- frameobj.texture_filesize = frame[1];
- frameobj.offx = frame[2];
- frameobj.offy = frame[3];
- frameobj.width = frame[4];
- frameobj.height = frame[5];
- frameobj.duration = frame[6];
- frameobj.hotspotX = frame[7];
- frameobj.hotspotY = frame[8];
- frameobj.image_points = frame[9];
- frameobj.poly_pts = frame[10];
- frameobj.pixelformat = frame[11];
- frameobj.spritesheeted = (frameobj.width !== 0);
- frameobj.datauri = ""; // generated on demand and cached
- frameobj.getDataUri = frame_getDataUri;
- console.log(frame);
- uv = {};
- uv.left = 0;
- uv.top = 0;
- uv.right = 1;
- uv.bottom = 1;
- frameobj.sheetTex = uv;
- frameobj.webGL_texture = null;
- wt = this.runtime.findWaitingTexture(frame[0]);
- if (wt)
- {
- frameobj.texture_img = wt;
- }
- else
- {
- frameobj.texture_img = new Image();
- frameobj.texture_img.cr_src = frame[0];
- frameobj.texture_img.cr_filesize = frame[1];
- frameobj.texture_img.c2webGL_texture = null;
- this.runtime.waitForImageLoad(frameobj.texture_img, frame[0]);
- }
- cr.seal(frameobj);
- animobj.frames.push(frameobj);
- this.all_frames.push(frameobj);
- }
- cr.seal(animobj);
- this.animations[i] = animobj; // swap array data for object
- }
- };
- typeProto.updateAllCurrentTexture = function ()
- {
- var i, len, inst;
- for (i = 0, len = this.instances.length; i < len; i++)
- {
- inst = this.instances[i];
- inst.curWebGLTexture = inst.curFrame.webGL_texture;
- }
- };
- typeProto.onLostWebGLContext = function ()
- {
- if (this.is_family)
- return;
- var i, len, frame;
- for (i = 0, len = this.all_frames.length; i < len; ++i)
- {
- frame = this.all_frames[i];
- frame.texture_img.c2webGL_texture = null;
- frame.webGL_texture = null;
- }
- this.has_loaded_textures = false;
- this.updateAllCurrentTexture();
- };
- typeProto.onRestoreWebGLContext = function ()
- {
- if (this.is_family || !this.instances.length)
- return;
- var i, len, frame;
- for (i = 0, len = this.all_frames.length; i < len; ++i)
- {
- frame = this.all_frames[i];
- frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
- }
- this.updateAllCurrentTexture();
- };
- typeProto.loadTextures = function ()
- {
- if (this.is_family || this.has_loaded_textures || !this.runtime.glwrap)
- return;
- var i, len, frame;
- for (i = 0, len = this.all_frames.length; i < len; ++i)
- {
- frame = this.all_frames[i];
- frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
- }
- this.has_loaded_textures = true;
- };
- typeProto.unloadTextures = function ()
- {
- if (this.is_family || this.instances.length || !this.has_loaded_textures)
- return;
- var i, len, frame;
- for (i = 0, len = this.all_frames.length; i < len; ++i)
- {
- frame = this.all_frames[i];
- this.runtime.glwrap.deleteTexture(frame.webGL_texture);
- frame.webGL_texture = null;
- }
- this.has_loaded_textures = false;
- };
- var already_drawn_images = [];
- typeProto.preloadCanvas2D = function (ctx)
- {
- var i, len, frameimg;
- cr.clearArray(already_drawn_images);
- for (i = 0, len = this.all_frames.length; i < len; ++i)
- {
- frameimg = this.all_frames[i].texture_img;
- if (already_drawn_images.indexOf(frameimg) !== -1)
- continue;
- ctx.drawImage(frameimg, 0, 0);
- already_drawn_images.push(frameimg);
- }
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- var poly_pts = this.type.animations[0].frames[0].poly_pts;
- if (this.recycled)
- this.collision_poly.set_pts(poly_pts);
- else
- this.collision_poly = new cr.CollisionPoly(poly_pts);
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onCreate = function()
- {
- this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
- this.isTicking = false;
- this.inAnimTrigger = false;
- this.collisionsEnabled = (this.properties[3] !== 0);
- this.cur_animation = this.getAnimationByName(this.properties[1]) || this.type.animations[0];
- this.cur_frame = this.properties[2];
- if (this.cur_frame < 0)
- this.cur_frame = 0;
- if (this.cur_frame >= this.cur_animation.frames.length)
- this.cur_frame = this.cur_animation.frames.length - 1;
- var curanimframe = this.cur_animation.frames[this.cur_frame];
- this.collision_poly.set_pts(curanimframe.poly_pts);
- this.hotspotX = curanimframe.hotspotX;
- this.hotspotY = curanimframe.hotspotY;
- this.cur_anim_speed = this.cur_animation.speed;
- this.cur_anim_repeatto = this.cur_animation.repeatto;
- if (!(this.type.animations.length === 1 && this.type.animations[0].frames.length === 1) && this.cur_anim_speed !== 0)
- {
- this.runtime.tickMe(this);
- this.isTicking = true;
- }
- if (this.recycled)
- this.animTimer.reset();
- else
- this.animTimer = new cr.KahanAdder();
- this.frameStart = this.getNowTime();
- this.animPlaying = true;
- this.animRepeats = 0;
- this.animForwards = true;
- this.animTriggerName = "";
- this.changeAnimName = "";
- this.changeAnimFrom = 0;
- this.changeAnimFrame = -1;
- this.type.loadTextures();
- var i, leni, j, lenj;
- var anim, frame, uv, maintex;
- for (i = 0, leni = this.type.animations.length; i < leni; i++)
- {
- anim = this.type.animations[i];
- for (j = 0, lenj = anim.frames.length; j < lenj; j++)
- {
- frame = anim.frames[j];
- if (frame.width === 0)
- {
- frame.width = frame.texture_img.width;
- frame.height = frame.texture_img.height;
- }
- if (frame.spritesheeted)
- {
- maintex = frame.texture_img;
- uv = frame.sheetTex;
- uv.left = frame.offx / maintex.width;
- uv.top = frame.offy / maintex.height;
- uv.right = (frame.offx + frame.width) / maintex.width;
- uv.bottom = (frame.offy + frame.height) / maintex.height;
- if (frame.offx === 0 && frame.offy === 0 && frame.width === maintex.width && frame.height === maintex.height)
- {
- frame.spritesheeted = false;
- }
- }
- }
- }
- this.curFrame = this.cur_animation.frames[this.cur_frame];
- this.curWebGLTexture = this.curFrame.webGL_texture;
- };
- instanceProto.saveToJSON = function ()
- {
- var o = {
- "a": this.cur_animation.sid,
- "f": this.cur_frame,
- "cas": this.cur_anim_speed,
- "fs": this.frameStart,
- "ar": this.animRepeats,
- "at": this.animTimer.sum,
- "rt": this.cur_anim_repeatto
- };
- if (!this.animPlaying)
- o["ap"] = this.animPlaying;
- if (!this.animForwards)
- o["af"] = this.animForwards;
- return o;
- };
- instanceProto.loadFromJSON = function (o)
- {
- var anim = this.getAnimationBySid(o["a"]);
- if (anim)
- this.cur_animation = anim;
- this.cur_frame = o["f"];
- if (this.cur_frame < 0)
- this.cur_frame = 0;
- if (this.cur_frame >= this.cur_animation.frames.length)
- this.cur_frame = this.cur_animation.frames.length - 1;
- this.cur_anim_speed = o["cas"];
- this.frameStart = o["fs"];
- this.animRepeats = o["ar"];
- this.animTimer.reset();
- this.animTimer.sum = o["at"];
- this.animPlaying = o.hasOwnProperty("ap") ? o["ap"] : true;
- this.animForwards = o.hasOwnProperty("af") ? o["af"] : true;
- if (o.hasOwnProperty("rt"))
- this.cur_anim_repeatto = o["rt"];
- else
- this.cur_anim_repeatto = this.cur_animation.repeatto;
- this.curFrame = this.cur_animation.frames[this.cur_frame];
- this.curWebGLTexture = this.curFrame.webGL_texture;
- this.collision_poly.set_pts(this.curFrame.poly_pts);
- this.hotspotX = this.curFrame.hotspotX;
- this.hotspotY = this.curFrame.hotspotY;
- };
- instanceProto.animationFinish = function (reverse)
- {
- this.cur_frame = reverse ? 0 : this.cur_animation.frames.length - 1;
- this.animPlaying = false;
- this.animTriggerName = this.cur_animation.name;
- this.inAnimTrigger = true;
- this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished, this);
- this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnimFinished, this);
- this.inAnimTrigger = false;
- this.animRepeats = 0;
- };
- instanceProto.getNowTime = function()
- {
- return this.animTimer.sum;
- };
- instanceProto.tick = function()
- {
- this.animTimer.add(this.runtime.getDt(this));
- if (this.changeAnimName.length)
- this.doChangeAnim();
- if (this.changeAnimFrame >= 0)
- this.doChangeAnimFrame();
- var now = this.getNowTime();
- var cur_animation = this.cur_animation;
- var prev_frame = cur_animation.frames[this.cur_frame];
- var next_frame;
- var cur_frame_time = prev_frame.duration / this.cur_anim_speed;
- if (this.animPlaying && now >= this.frameStart + cur_frame_time)
- {
- if (this.animForwards)
- {
- this.cur_frame++;
- }
- else
- {
- this.cur_frame--;
- }
- this.frameStart += cur_frame_time;
- if (this.cur_frame >= cur_animation.frames.length)
- {
- if (cur_animation.pingpong)
- {
- this.animForwards = false;
- this.cur_frame = cur_animation.frames.length - 2;
- }
- else if (cur_animation.loop)
- {
- this.cur_frame = this.cur_anim_repeatto;
- }
- else
- {
- this.animRepeats++;
- if (this.animRepeats >= cur_animation.repeatcount)
- {
- this.animationFinish(false);
- }
- else
- {
- this.cur_frame = this.cur_anim_repeatto;
- }
- }
- }
- if (this.cur_frame < 0)
- {
- if (cur_animation.pingpong)
- {
- this.cur_frame = 1;
- this.animForwards = true;
- if (!cur_animation.loop)
- {
- this.animRepeats++;
- if (this.animRepeats >= cur_animation.repeatcount)
- {
- this.animationFinish(true);
- }
- }
- }
- else
- {
- if (cur_animation.loop)
- {
- this.cur_frame = this.cur_anim_repeatto;
- }
- else
- {
- this.animRepeats++;
- if (this.animRepeats >= cur_animation.repeatcount)
- {
- this.animationFinish(true);
- }
- else
- {
- this.cur_frame = this.cur_anim_repeatto;
- }
- }
- }
- }
- if (this.cur_frame < 0)
- this.cur_frame = 0;
- else if (this.cur_frame >= cur_animation.frames.length)
- this.cur_frame = cur_animation.frames.length - 1;
- if (now > this.frameStart + (cur_animation.frames[this.cur_frame].duration / this.cur_anim_speed))
- {
- this.frameStart = now;
- }
- next_frame = cur_animation.frames[this.cur_frame];
- this.OnFrameChanged(prev_frame, next_frame);
- this.runtime.redraw = true;
- }
- };
- instanceProto.getAnimationByName = function (name_)
- {
- var i, len, a;
- for (i = 0, len = this.type.animations.length; i < len; i++)
- {
- a = this.type.animations[i];
- if (cr.equals_nocase(a.name, name_))
- return a;
- }
- return null;
- };
- instanceProto.getAnimationBySid = function (sid_)
- {
- var i, len, a;
- for (i = 0, len = this.type.animations.length; i < len; i++)
- {
- a = this.type.animations[i];
- if (a.sid === sid_)
- return a;
- }
- return null;
- };
- instanceProto.doChangeAnim = function ()
- {
- var prev_frame = this.cur_animation.frames[this.cur_frame];
- var anim = this.getAnimationByName(this.changeAnimName);
- this.changeAnimName = "";
- if (!anim)
- return;
- if (cr.equals_nocase(anim.name, this.cur_animation.name) && this.animPlaying)
- return;
- this.cur_animation = anim;
- this.cur_anim_speed = anim.speed;
- this.cur_anim_repeatto = anim.repeatto;
- if (this.cur_frame < 0)
- this.cur_frame = 0;
- if (this.cur_frame >= this.cur_animation.frames.length)
- this.cur_frame = this.cur_animation.frames.length - 1;
- if (this.changeAnimFrom === 1)
- this.cur_frame = 0;
- this.animPlaying = true;
- this.frameStart = this.getNowTime();
- this.animForwards = true;
- this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
- this.runtime.redraw = true;
- };
- instanceProto.doChangeAnimFrame = function ()
- {
- var prev_frame = this.cur_animation.frames[this.cur_frame];
- var prev_frame_number = this.cur_frame;
- this.cur_frame = cr.floor(this.changeAnimFrame);
- if (this.cur_frame < 0)
- this.cur_frame = 0;
- if (this.cur_frame >= this.cur_animation.frames.length)
- this.cur_frame = this.cur_animation.frames.length - 1;
- if (prev_frame_number !== this.cur_frame)
- {
- this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
- this.frameStart = this.getNowTime();
- this.runtime.redraw = true;
- }
- this.changeAnimFrame = -1;
- };
- instanceProto.OnFrameChanged = function (prev_frame, next_frame)
- {
- var oldw = prev_frame.width;
- var oldh = prev_frame.height;
- var neww = next_frame.width;
- var newh = next_frame.height;
- if (oldw != neww)
- this.width *= (neww / oldw);
- if (oldh != newh)
- this.height *= (newh / oldh);
- this.hotspotX = next_frame.hotspotX;
- this.hotspotY = next_frame.hotspotY;
- this.collision_poly.set_pts(next_frame.poly_pts);
- this.set_bbox_changed();
- this.curFrame = next_frame;
- this.curWebGLTexture = next_frame.webGL_texture;
- var i, len, b;
- for (i = 0, len = this.behavior_insts.length; i < len; i++)
- {
- b = this.behavior_insts[i];
- if (b.onSpriteFrameChanged)
- b.onSpriteFrameChanged(prev_frame, next_frame);
- }
- this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnFrameChanged, this);
- };
- instanceProto.draw = function(ctx)
- {
- ctx.globalAlpha = this.opacity;
- var cur_frame = this.curFrame;
- var spritesheeted = cur_frame.spritesheeted;
- var cur_image = cur_frame.texture_img;
- var myx = this.x;
- var myy = this.y;
- var w = this.width;
- var h = this.height;
- if (this.angle === 0 && w >= 0 && h >= 0)
- {
- myx -= this.hotspotX * w;
- myy -= this.hotspotY * h;
- if (this.runtime.pixel_rounding)
- {
- myx = Math.round(myx);
- myy = Math.round(myy);
- }
- if (spritesheeted)
- {
- ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
- myx, myy, w, h);
- }
- else
- {
- ctx.drawImage(cur_image, myx, myy, w, h);
- }
- }
- else
- {
- if (this.runtime.pixel_rounding)
- {
- myx = Math.round(myx);
- myy = Math.round(myy);
- }
- ctx.save();
- var widthfactor = w > 0 ? 1 : -1;
- var heightfactor = h > 0 ? 1 : -1;
- ctx.translate(myx, myy);
- if (widthfactor !== 1 || heightfactor !== 1)
- ctx.scale(widthfactor, heightfactor);
- ctx.rotate(this.angle * widthfactor * heightfactor);
- var drawx = 0 - (this.hotspotX * cr.abs(w))
- var drawy = 0 - (this.hotspotY * cr.abs(h));
- if (spritesheeted)
- {
- ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
- drawx, drawy, cr.abs(w), cr.abs(h));
- }
- else
- {
- ctx.drawImage(cur_image, drawx, drawy, cr.abs(w), cr.abs(h));
- }
- ctx.restore();
- }
- /*
- ctx.strokeStyle = "#f00";
- ctx.lineWidth = 3;
- ctx.beginPath();
- this.collision_poly.cache_poly(this.width, this.height, this.angle);
- var i, len, ax, ay, bx, by;
- for (i = 0, len = this.collision_poly.pts_count; i < len; i++)
- {
- ax = this.collision_poly.pts_cache[i*2] + this.x;
- ay = this.collision_poly.pts_cache[i*2+1] + this.y;
- bx = this.collision_poly.pts_cache[((i+1)%len)*2] + this.x;
- by = this.collision_poly.pts_cache[((i+1)%len)*2+1] + this.y;
- ctx.moveTo(ax, ay);
- ctx.lineTo(bx, by);
- }
- ctx.stroke();
- ctx.closePath();
- */
- /*
- if (this.behavior_insts.length >= 1 && this.behavior_insts[0].draw)
- {
- this.behavior_insts[0].draw(ctx);
- }
- */
- };
- instanceProto.drawGL_earlyZPass = function(glw)
- {
- this.drawGL(glw);
- };
- instanceProto.drawGL = function(glw)
- {
- glw.setTexture(this.curWebGLTexture);
- glw.setOpacity(this.opacity);
- var cur_frame = this.curFrame;
- var q = this.bquad;
- if (this.runtime.pixel_rounding)
- {
- var ox = Math.round(this.x) - this.x;
- var oy = Math.round(this.y) - this.y;
- if (cur_frame.spritesheeted)
- glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, cur_frame.sheetTex);
- else
- glw.quad(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy);
- }
- else
- {
- if (cur_frame.spritesheeted)
- glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, cur_frame.sheetTex);
- else
- glw.quad(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly);
- }
- };
- instanceProto.getImagePointIndexByName = function(name_)
- {
- var cur_frame = this.curFrame;
- var i, len;
- for (i = 0, len = cur_frame.image_points.length; i < len; i++)
- {
- if (cr.equals_nocase(name_, cur_frame.image_points[i][0]))
- return i;
- }
- return -1;
- };
- instanceProto.getImagePoint = function(imgpt, getX)
- {
- var cur_frame = this.curFrame;
- var image_points = cur_frame.image_points;
- var index;
- if (cr.is_string(imgpt))
- index = this.getImagePointIndexByName(imgpt);
- else
- index = imgpt - 1; // 0 is origin
- index = cr.floor(index);
- if (index < 0 || index >= image_points.length)
- return getX ? this.x : this.y; // return origin
- var x = (image_points[index][1] - cur_frame.hotspotX) * this.width;
- var y = image_points[index][2];
- y = (y - cur_frame.hotspotY) * this.height;
- var cosa = Math.cos(this.angle);
- var sina = Math.sin(this.angle);
- var x_temp = (x * cosa) - (y * sina);
- y = (y * cosa) + (x * sina);
- x = x_temp;
- x += this.x;
- y += this.y;
- return getX ? x : y;
- };
- function Cnds() {};
- var arrCache = [];
- function allocArr()
- {
- if (arrCache.length)
- return arrCache.pop();
- else
- return [0, 0, 0];
- };
- function freeArr(a)
- {
- a[0] = 0;
- a[1] = 0;
- a[2] = 0;
- arrCache.push(a);
- };
- function makeCollKey(a, b)
- {
- if (a < b)
- return "" + a + "," + b;
- else
- return "" + b + "," + a;
- };
- function collmemory_add(collmemory, a, b, tickcount)
- {
- var a_uid = a.uid;
- var b_uid = b.uid;
- var key = makeCollKey(a_uid, b_uid);
- if (collmemory.hasOwnProperty(key))
- {
- collmemory[key][2] = tickcount;
- return;
- }
- var arr = allocArr();
- arr[0] = a_uid;
- arr[1] = b_uid;
- arr[2] = tickcount;
- collmemory[key] = arr;
- };
- function collmemory_remove(collmemory, a, b)
- {
- var key = makeCollKey(a.uid, b.uid);
- if (collmemory.hasOwnProperty(key))
- {
- freeArr(collmemory[key]);
- delete collmemory[key];
- }
- };
- function collmemory_removeInstance(collmemory, inst)
- {
- var uid = inst.uid;
- var p, entry;
- for (p in collmemory)
- {
- if (collmemory.hasOwnProperty(p))
- {
- entry = collmemory[p];
- if (entry[0] === uid || entry[1] === uid)
- {
- freeArr(collmemory[p]);
- delete collmemory[p];
- }
- }
- }
- };
- var last_coll_tickcount = -2;
- function collmemory_has(collmemory, a, b)
- {
- var key = makeCollKey(a.uid, b.uid);
- if (collmemory.hasOwnProperty(key))
- {
- last_coll_tickcount = collmemory[key][2];
- return true;
- }
- else
- {
- last_coll_tickcount = -2;
- return false;
- }
- };
- var candidates1 = [];
- Cnds.prototype.OnCollision = function (rtype)
- {
- if (!rtype)
- return false;
- var runtime = this.runtime;
- var cnd = runtime.getCurrentCondition();
- var ltype = cnd.type;
- var collmemory = null;
- if (cnd.extra["collmemory"])
- {
- collmemory = cnd.extra["collmemory"];
- }
- else
- {
- collmemory = {};
- cnd.extra["collmemory"] = collmemory;
- }
- if (!cnd.extra["spriteCreatedDestroyCallback"])
- {
- cnd.extra["spriteCreatedDestroyCallback"] = true;
- runtime.addDestroyCallback(function(inst) {
- collmemory_removeInstance(cnd.extra["collmemory"], inst);
- });
- }
- var lsol = ltype.getCurrentSol();
- var rsol = rtype.getCurrentSol();
- var linstances = lsol.getObjects();
- var rinstances;
- var registeredInstances;
- var l, linst, r, rinst;
- var curlsol, currsol;
- var tickcount = this.runtime.tickcount;
- var lasttickcount = tickcount - 1;
- var exists, run;
- var current_event = runtime.getCurrentEventStack().current_event;
- var orblock = current_event.orblock;
- for (l = 0; l < linstances.length; l++)
- {
- linst = linstances[l];
- if (rsol.select_all)
- {
- linst.update_bbox();
- this.runtime.getCollisionCandidates(linst.layer, rtype, linst.bbox, candidates1);
- rinstances = candidates1;
- this.runtime.addRegisteredCollisionCandidates(linst, rtype, rinstances);
- }
- else
- {
- rinstances = rsol.getObjects();
- }
- for (r = 0; r < rinstances.length; r++)
- {
- rinst = rinstances[r];
- if (runtime.testOverlap(linst, rinst) || runtime.checkRegisteredCollision(linst, rinst))
- {
- exists = collmemory_has(collmemory, linst, rinst);
- run = (!exists || (last_coll_tickcount < lasttickcount));
- collmemory_add(collmemory, linst, rinst, tickcount);
- if (run)
- {
- runtime.pushCopySol(current_event.solModifiers);
- curlsol = ltype.getCurrentSol();
- currsol = rtype.getCurrentSol();
- curlsol.select_all = false;
- currsol.select_all = false;
- if (ltype === rtype)
- {
- curlsol.instances.length = 2; // just use lsol, is same reference as rsol
- curlsol.instances[0] = linst;
- curlsol.instances[1] = rinst;
- ltype.applySolToContainer();
- }
- else
- {
- curlsol.instances.length = 1;
- currsol.instances.length = 1;
- curlsol.instances[0] = linst;
- currsol.instances[0] = rinst;
- ltype.applySolToContainer();
- rtype.applySolToContainer();
- }
- current_event.retrigger();
- runtime.popSol(current_event.solModifiers);
- }
- }
- else
- {
- collmemory_remove(collmemory, linst, rinst);
- }
- }
- cr.clearArray(candidates1);
- }
- return false;
- };
- var rpicktype = null;
- var rtopick = new cr.ObjectSet();
- var needscollisionfinish = false;
- var candidates2 = [];
- var temp_bbox = new cr.rect(0, 0, 0, 0);
- function DoOverlapCondition(rtype, offx, offy)
- {
- if (!rtype)
- return false;
- var do_offset = (offx !== 0 || offy !== 0);
- var oldx, oldy, ret = false, r, lenr, rinst;
- var cnd = this.runtime.getCurrentCondition();
- var ltype = cnd.type;
- var inverted = cnd.inverted;
- var rsol = rtype.getCurrentSol();
- var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
- var rinstances;
- if (rsol.select_all)
- {
- this.update_bbox();
- temp_bbox.copy(this.bbox);
- temp_bbox.offset(offx, offy);
- this.runtime.getCollisionCandidates(this.layer, rtype, temp_bbox, candidates2);
- rinstances = candidates2;
- }
- else if (orblock)
- {
- if (this.runtime.isCurrentConditionFirst() && !rsol.else_instances.length && rsol.instances.length)
- rinstances = rsol.instances;
- else
- rinstances = rsol.else_instances;
- }
- else
- {
- rinstances = rsol.instances;
- }
- rpicktype = rtype;
- needscollisionfinish = (ltype !== rtype && !inverted);
- if (do_offset)
- {
- oldx = this.x;
- oldy = this.y;
- this.x += offx;
- this.y += offy;
- this.set_bbox_changed();
- }
- for (r = 0, lenr = rinstances.length; r < lenr; r++)
- {
- rinst = rinstances[r];
- if (this.runtime.testOverlap(this, rinst))
- {
- ret = true;
- if (inverted)
- break;
- if (ltype !== rtype)
- rtopick.add(rinst);
- }
- }
- if (do_offset)
- {
- this.x = oldx;
- this.y = oldy;
- this.set_bbox_changed();
- }
- cr.clearArray(candidates2);
- return ret;
- };
- typeProto.finish = function (do_pick)
- {
- if (!needscollisionfinish)
- return;
- if (do_pick)
- {
- var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
- var sol = rpicktype.getCurrentSol();
- var topick = rtopick.valuesRef();
- var i, len, inst;
- if (sol.select_all)
- {
- sol.select_all = false;
- cr.clearArray(sol.instances);
- for (i = 0, len = topick.length; i < len; ++i)
- {
- sol.instances[i] = topick[i];
- }
- if (orblock)
- {
- cr.clearArray(sol.else_instances);
- for (i = 0, len = rpicktype.instances.length; i < len; ++i)
- {
- inst = rpicktype.instances[i];
- if (!rtopick.contains(inst))
- sol.else_instances.push(inst);
- }
- }
- }
- else
- {
- if (orblock)
- {
- var initsize = sol.instances.length;
- for (i = 0, len = topick.length; i < len; ++i)
- {
- sol.instances[initsize + i] = topick[i];
- cr.arrayFindRemove(sol.else_instances, topick[i]);
- }
- }
- else
- {
- cr.shallowAssignArray(sol.instances, topick);
- }
- }
- rpicktype.applySolToContainer();
- }
- rtopick.clear();
- needscollisionfinish = false;
- };
- Cnds.prototype.IsOverlapping = function (rtype)
- {
- return DoOverlapCondition.call(this, rtype, 0, 0);
- };
- Cnds.prototype.IsOverlappingOffset = function (rtype, offx, offy)
- {
- return DoOverlapCondition.call(this, rtype, offx, offy);
- };
- Cnds.prototype.IsAnimPlaying = function (animname)
- {
- if (this.changeAnimName.length)
- return cr.equals_nocase(this.changeAnimName, animname);
- else
- return cr.equals_nocase(this.cur_animation.name, animname);
- };
- Cnds.prototype.CompareFrame = function (cmp, framenum)
- {
- return cr.do_cmp(this.cur_frame, cmp, framenum);
- };
- Cnds.prototype.CompareAnimSpeed = function (cmp, x)
- {
- var s = (this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
- return cr.do_cmp(s, cmp, x);
- };
- Cnds.prototype.OnAnimFinished = function (animname)
- {
- return cr.equals_nocase(this.animTriggerName, animname);
- };
- Cnds.prototype.OnAnyAnimFinished = function ()
- {
- return true;
- };
- Cnds.prototype.OnFrameChanged = function ()
- {
- return true;
- };
- Cnds.prototype.IsMirrored = function ()
- {
- return this.width < 0;
- };
- Cnds.prototype.IsFlipped = function ()
- {
- return this.height < 0;
- };
- Cnds.prototype.OnURLLoaded = function ()
- {
- return true;
- };
- Cnds.prototype.IsCollisionEnabled = function ()
- {
- return this.collisionsEnabled;
- };
- Cnds.prototype.colorChanged = function ()
- {
- return true;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.Spawn = function (obj, layer, imgpt)
- {
- if (!obj || !layer)
- return;
- var inst = this.runtime.createInstance(obj, layer, this.getImagePoint(imgpt, true), this.getImagePoint(imgpt, false));
- if (!inst)
- return;
- if (typeof inst.angle !== "undefined")
- {
- inst.angle = this.angle;
- inst.set_bbox_changed();
- }
- this.runtime.isInOnDestroy++;
- var i, len, s;
- this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
- if (inst.is_contained)
- {
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- s = inst.siblings[i];
- this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
- }
- }
- this.runtime.isInOnDestroy--;
- var cur_act = this.runtime.getCurrentAction();
- var reset_sol = false;
- if (cr.is_undefined(cur_act.extra["Spawn_LastExec"]) || cur_act.extra["Spawn_LastExec"] < this.runtime.execcount)
- {
- reset_sol = true;
- cur_act.extra["Spawn_LastExec"] = this.runtime.execcount;
- }
- var sol;
- if (obj != this.type)
- {
- sol = obj.getCurrentSol();
- sol.select_all = false;
- if (reset_sol)
- {
- cr.clearArray(sol.instances);
- sol.instances[0] = inst;
- }
- else
- sol.instances.push(inst);
- if (inst.is_contained)
- {
- for (i = 0, len = inst.siblings.length; i < len; i++)
- {
- s = inst.siblings[i];
- sol = s.type.getCurrentSol();
- sol.select_all = false;
- if (reset_sol)
- {
- cr.clearArray(sol.instances);
- sol.instances[0] = s;
- }
- else
- sol.instances.push(s);
- }
- }
- }
- };
- Acts.prototype.SetEffect = function (effect)
- {
- this.blend_mode = effect;
- this.compositeOp = cr.effectToCompositeOp(effect);
- cr.setGLBlend(this, effect, this.runtime.gl);
- this.runtime.redraw = true;
- };
- Acts.prototype.StopAnim = function ()
- {
- this.animPlaying = false;
- };
- Acts.prototype.StartAnim = function (from)
- {
- this.animPlaying = true;
- this.frameStart = this.getNowTime();
- if (from === 1 && this.cur_frame !== 0)
- {
- this.changeAnimFrame = 0;
- if (!this.inAnimTrigger)
- this.doChangeAnimFrame();
- }
- if (!this.isTicking)
- {
- this.runtime.tickMe(this);
- this.isTicking = true;
- }
- };
- Acts.prototype.SetAnim = function (animname, from)
- {
- this.changeAnimName = animname;
- this.changeAnimFrom = from;
- if (!this.isTicking)
- {
- this.runtime.tickMe(this);
- this.isTicking = true;
- }
- if (!this.inAnimTrigger)
- this.doChangeAnim();
- };
- Acts.prototype.SetAnimFrame = function (framenumber)
- {
- this.changeAnimFrame = framenumber;
- if (!this.isTicking)
- {
- this.runtime.tickMe(this);
- this.isTicking = true;
- }
- if (!this.inAnimTrigger)
- this.doChangeAnimFrame();
- };
- Acts.prototype.SetAnimSpeed = function (s)
- {
- this.cur_anim_speed = cr.abs(s);
- this.animForwards = (s >= 0);
- if (!this.isTicking)
- {
- this.runtime.tickMe(this);
- this.isTicking = true;
- }
- };
- Acts.prototype.SetAnimRepeatToFrame = function (s)
- {
- s = Math.floor(s);
- if (s < 0)
- s = 0;
- if (s >= this.cur_animation.frames.length)
- s = this.cur_animation.frames.length - 1;
- this.cur_anim_repeatto = s;
- };
- Acts.prototype.SetMirrored = function (m)
- {
- var neww = cr.abs(this.width) * (m === 0 ? -1 : 1);
- if (this.width === neww)
- return;
- this.width = neww;
- this.set_bbox_changed();
- };
- Acts.prototype.SetFlipped = function (f)
- {
- var newh = cr.abs(this.height) * (f === 0 ? -1 : 1);
- if (this.height === newh)
- return;
- this.height = newh;
- this.set_bbox_changed();
- };
- Acts.prototype.SetScale = function (s)
- {
- var cur_frame = this.curFrame;
- var mirror_factor = (this.width < 0 ? -1 : 1);
- var flip_factor = (this.height < 0 ? -1 : 1);
- var new_width = cur_frame.width * s * mirror_factor;
- var new_height = cur_frame.height * s * flip_factor;
- if (this.width !== new_width || this.height !== new_height)
- {
- this.width = new_width;
- this.height = new_height;
- this.set_bbox_changed();
- }
- };
- Acts.prototype.LoadURL = function (url_, resize_, crossOrigin_)
- {
- var img = new Image();
- var self = this;
- var curFrame_ = this.curFrame;
- img.onload = function ()
- {
- if (curFrame_.texture_img.src === img.src)
- {
- if (self.runtime.glwrap && self.curFrame === curFrame_)
- self.curWebGLTexture = curFrame_.webGL_texture;
- if (resize_ === 0) // resize to image size
- {
- self.width = img.width;
- self.height = img.height;
- self.set_bbox_changed();
- }
- self.runtime.redraw = true;
- self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
- return;
- }
- curFrame_.texture_img = img;
- curFrame_.offx = 0;
- curFrame_.offy = 0;
- curFrame_.width = img.width;
- curFrame_.height = img.height;
- curFrame_.spritesheeted = false;
- curFrame_.datauri = "";
- curFrame_.pixelformat = 0; // reset to RGBA, since we don't know what type of image will have come in
- if (self.runtime.glwrap)
- {
- if (curFrame_.webGL_texture)
- self.runtime.glwrap.deleteTexture(curFrame_.webGL_texture);
- curFrame_.webGL_texture = self.runtime.glwrap.loadTexture(img, false, self.runtime.linearSampling);
- if (self.curFrame === curFrame_)
- self.curWebGLTexture = curFrame_.webGL_texture;
- self.type.updateAllCurrentTexture();
- }
- if (resize_ === 0) // resize to image size
- {
- self.width = img.width;
- self.height = img.height;
- self.set_bbox_changed();
- }
- self.runtime.redraw = true;
- self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
- };
- if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
- img["crossOrigin"] = "anonymous";
- this.runtime.setImageSrc(img, url_);
- };
- Acts.prototype.SetCollisions = function (set_)
- {
- if (this.collisionsEnabled === (set_ !== 0))
- return; // no change
- this.collisionsEnabled = (set_ !== 0);
- if (this.collisionsEnabled)
- this.set_bbox_changed(); // needs to be added back to cells
- else
- {
- if (this.collcells.right >= this.collcells.left)
- this.type.collision_grid.update(this, this.collcells, null);
- this.collcells.set(0, 0, -1, -1);
- }
- };
- Acts.prototype.SetAnimColor = function (color)
- {
- let self = this;
- if (this.curFrame && this.curFrame.getDataUri)
- {
- const datauri = self.curFrame.getDataUri();
- console.log(datauri);
- const img = new Image();
- img.src = datauri;
- img.onload = function() {
- const canvas = document.createElement("canvas");
- canvas.width = self.curFrame.width;
- canvas.height = self.curFrame.height;
- const ctx = canvas.getContext("2d");
- ctx.drawImage(img, 0, 0);
- ctx.globalCompositeOperation = "source-atop";
- ctx.fillStyle = color;
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- self.ImageColorChanged = canvas.toDataURL();
- self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.colorChanged, self);
- }
- }
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.AnimationFrame = function (ret)
- {
- ret.set_int(this.cur_frame);
- };
- Exps.prototype.AnimationFrameCount = function (ret)
- {
- ret.set_int(this.cur_animation.frames.length);
- };
- Exps.prototype.AnimationName = function (ret)
- {
- ret.set_string(this.cur_animation.name);
- };
- Exps.prototype.AnimationSpeed = function (ret)
- {
- ret.set_float(this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
- };
- Exps.prototype.ImagePointX = function (ret, imgpt)
- {
- ret.set_float(this.getImagePoint(imgpt, true));
- };
- Exps.prototype.ImagePointY = function (ret, imgpt)
- {
- ret.set_float(this.getImagePoint(imgpt, false));
- };
- Exps.prototype.ImagePointCount = function (ret)
- {
- ret.set_int(this.curFrame.image_points.length);
- };
- Exps.prototype.ImageWidth = function (ret)
- {
- ret.set_float(this.curFrame.width);
- };
- Exps.prototype.ImageHeight = function (ret)
- {
- ret.set_float(this.curFrame.height);
- };
- Exps.prototype.ImageColorChanged = function (ret)
- {
- ret.set_string(this.ImageColorChanged);
- };
- pluginProto.exps = new Exps();
-}());
-/* global cr,log,assert2 */
-/* jshint globalstrict: true */
-/* jshint strict: true */
-;
-;
-var jText = '';
-cr.plugins_.SpriteFontPlus = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.SpriteFontPlus.prototype;
- pluginProto.onCreate = function ()
- {
- };
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- if (this.is_family)
- return;
- this.texture_img = new Image();
- this.texture_img["idtkLoadDisposed"] = true;
- this.texture_img.src = this.texture_file;
- this.runtime.wait_for_textures.push(this.texture_img);
- this.webGL_texture = null;
- };
- typeProto.onLostWebGLContext = function ()
- {
- if (this.is_family)
- return;
- this.webGL_texture = null;
- };
- typeProto.onRestoreWebGLContext = function ()
- {
- if (this.is_family || !this.instances.length)
- return;
- if (!this.webGL_texture)
- {
- this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, false, this.runtime.linearSampling, this.texture_pixelformat);
- }
- var i, len;
- for (i = 0, len = this.instances.length; i < len; i++)
- this.instances[i].webGL_texture = this.webGL_texture;
- };
- typeProto.unloadTextures = function ()
- {
- if (this.is_family || this.instances.length || !this.webGL_texture)
- return;
- this.runtime.glwrap.deleteTexture(this.webGL_texture);
- this.webGL_texture = null;
- };
- typeProto.preloadCanvas2D = function (ctx)
- {
- ctx.drawImage(this.texture_img, 0, 0);
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- };
- var instanceProto = pluginProto.Instance.prototype;
- instanceProto.onDestroy = function()
- {
- freeAllLines (this.lines);
- freeAllClip (this.clipList);
- freeAllClipUV(this.clipUV);
- cr.wipe(this.characterWidthList);
- };
- instanceProto.onCreate = function()
- {
- this.texture_img = this.type.texture_img;
- this.characterWidth = this.properties[0];
- this.characterHeight = this.properties[1];
- this.characterSet = this.properties[2];
- this.text = this.properties[3];
- this.characterScale = this.properties[4];
- this.visible = (this.properties[5] === 0); // 0=visible, 1=invisible
- this.halign = this.properties[6]/2.0; // 0=left, 1=center, 2=right
- this.valign = this.properties[7]/2.0; // 0=top, 1=center, 2=bottom
- this.wrapbyword = (this.properties[9] === 0); // 0=word, 1=character
- this.characterSpacing = this.properties[10];
- this.lineHeight = this.properties[11];
- this.textWidth = 0;
- this.textHeight = 0;
- this.charWidthJSON = this.properties[12];
- this.spaceWidth = this.properties[13];
- jText = this.charWidthJSON;
- if (this.recycled)
- {
- this.lines.length = 0;
- cr.wipe(this.clipList);
- cr.wipe(this.clipUV);
- cr.wipe(this.characterWidthList);
- }
- else
- {
- this.lines = [];
- this.clipList = {};
- this.clipUV = {};
- this.characterWidthList = {};
- }
- try{
- if(this.charWidthJSON){
- if(this.charWidthJSON.indexOf('""c2array""') !== -1) {
- var jStr = jQuery.parseJSON(this.charWidthJSON.replace(/""/g,'"'));
- var l = jStr.size[1];
- for(var s = 0; s < l; s++) {
- var cs = jStr.data[1][s][0];
- var w = jStr.data[0][s][0];
- for(var c = 0; c < cs.length; c++) {
- this.characterWidthList[cs.charAt(c)] = w
- }
- }
- } else {
- var jStr = jQuery.parseJSON(this.charWidthJSON);
- var l = jStr.length;
- for(var s = 0; s < l; s++) {
- var cs = jStr[s][1];
- var w = jStr[s][0];
- for(var c = 0; c < cs.length; c++) {
- this.characterWidthList[cs.charAt(c)] = w
- }
- }
- }
- }
- if(this.spaceWidth !== -1) {
- this.characterWidthList[' '] = this.spaceWidth;
- }
- }
- catch(e){
- if(window.console && window.console.log) {
- window.console.log('SpriteFont+ Failure: ' + e);
- }
- }
- this.text_changed = true;
- this.lastwrapwidth = this.width;
- if (this.runtime.glwrap)
- {
- if (!this.type.webGL_texture)
- {
- this.type.webGL_texture = this.runtime.glwrap.loadTexture(this.type.texture_img, false, this.runtime.linearSampling, this.type.texture_pixelformat);
- }
- this.webGL_texture = this.type.webGL_texture;
- }
- this.SplitSheet();
- };
- instanceProto.saveToJSON = function ()
- {
- var save = {
- "t": this.text,
- "csc": this.characterScale,
- "csp": this.characterSpacing,
- "lh": this.lineHeight,
- "tw": this.textWidth,
- "th": this.textHeight,
- "lrt": this.last_render_tick,
- "cw": {}
- };
- for (var ch in this.characterWidthList)
- save["cw"][ch] = this.characterWidthList[ch];
- return save;
- };
- instanceProto.loadFromJSON = function (o)
- {
- this.text = o["t"];
- this.characterScale = o["csc"];
- this.characterSpacing = o["csp"];
- this.lineHeight = o["lh"];
- this.textWidth = o["tw"];
- this.textHeight = o["th"];
- this.last_render_tick = o["lrt"];
- for(var ch in o["cw"])
- this.characterWidthList[ch] = o["cw"][ch];
- this.text_changed = true;
- this.lastwrapwidth = this.width;
- };
- function trimRight(text)
- {
- return text.replace(/\s\s*$/, '');
- }
- var MAX_CACHE_SIZE = 1000;
- function alloc(cache,Constructor)
- {
- if (cache.length)
- return cache.pop();
- else
- return new Constructor();
- }
- function free(cache,data)
- {
- if (cache.length < MAX_CACHE_SIZE)
- {
- cache.push(data);
- }
- }
- function freeAll(cache,dataList,isArray)
- {
- if (isArray) {
- var i, len;
- for (i = 0, len = dataList.length; i < len; i++)
- {
- free(cache,dataList[i]);
- }
- dataList.length = 0;
- } else {
- var prop;
- for(prop in dataList) {
- if(Object.prototype.hasOwnProperty.call(dataList,prop)) {
- free(cache,dataList[prop]);
- delete dataList[prop];
- }
- }
- }
- }
- function addLine(inst,lineIndex,cur_line) {
- var lines = inst.lines;
- var line;
- cur_line = trimRight(cur_line);
- if (lineIndex >= lines.length)
- lines.push(allocLine());
- line = lines[lineIndex];
- line.text = cur_line;
- line.width = inst.measureWidth(cur_line);
- inst.textWidth = cr.max(inst.textWidth,line.width);
- }
- var linesCache = [];
- function allocLine() { return alloc(linesCache,Object); }
- function freeLine(l) { free(linesCache,l); }
- function freeAllLines(arr) { freeAll(linesCache,arr,true); }
- function addClip(obj,property,x,y,w,h) {
- if (obj[property] === undefined) {
- obj[property] = alloc(clipCache,Object);
- }
- obj[property].x = x;
- obj[property].y = y;
- obj[property].w = w;
- obj[property].h = h;
- }
- var clipCache = [];
- function allocClip() { return alloc(clipCache,Object); }
- function freeAllClip(obj) { freeAll(clipCache,obj,false);}
- function addClipUV(obj,property,left,top,right,bottom) {
- if (obj[property] === undefined) {
- obj[property] = alloc(clipUVCache,cr.rect);
- }
- obj[property].left = left;
- obj[property].top = top;
- obj[property].right = right;
- obj[property].bottom = bottom;
- }
- var clipUVCache = [];
- function allocClipUV() { return alloc(clipUVCache,cr.rect);}
- function freeAllClipUV(obj) { freeAll(clipUVCache,obj,false);}
- instanceProto.SplitSheet = function() {
- var texture = this.texture_img;
- var texWidth = texture.width;
- var texHeight = texture.height;
- var charWidth = this.characterWidth;
- var charHeight = this.characterHeight;
- var charU = charWidth /texWidth;
- var charV = charHeight/texHeight;
- var charSet = this.characterSet ;
- var cols = Math.floor(texWidth/charWidth);
- var rows = Math.floor(texHeight/charHeight);
- for ( var c = 0; c < charSet.length; c++) {
- if (c >= cols * rows) break;
- var x = c%cols;
- var y = Math.floor(c/cols);
- var letter = charSet.charAt(c);
- if (this.runtime.glwrap) {
- addClipUV(
- this.clipUV, letter,
- x * charU ,
- y * charV ,
- (x+1) * charU ,
- (y+1) * charV
- );
- } else {
- addClip(
- this.clipList, letter,
- x * charWidth,
- y * charHeight,
- charWidth,
- charHeight
- );
- }
- }
- };
- /*
- * Word-Wrapping
- */
- var wordsCache = [];
- pluginProto.TokeniseWords = function (text)
- {
- wordsCache.length = 0;
- var cur_word = "";
- var ch;
- var i = 0;
- while (i < text.length)
- {
- ch = text.charAt(i);
- if (ch === "\n")
- {
- if (cur_word.length)
- {
- wordsCache.push(cur_word);
- cur_word = "";
- }
- wordsCache.push("\n");
- ++i;
- }
- else if (ch === " " || ch === "\t" || ch === "-")
- {
- do {
- cur_word += text.charAt(i);
- i++;
- }
- while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
- wordsCache.push(cur_word);
- cur_word = "";
- }
- else if (i < text.length)
- {
- cur_word += ch;
- i++;
- }
- }
- if (cur_word.length)
- wordsCache.push(cur_word);
- };
- pluginProto.WordWrap = function (inst)
- {
- var text = inst.text;
- var lines = inst.lines;
- if (!text || !text.length)
- {
- freeAllLines(lines);
- return;
- }
- var width = inst.width;
- if (width <= 2.0)
- {
- freeAllLines(lines);
- return;
- }
- var charWidth = inst.characterWidth;
- var charScale = inst.characterScale;
- var charSpacing = inst.characterSpacing;
- if ( (text.length * (charWidth * charScale + charSpacing) - charSpacing) <= width && text.indexOf("\n") === -1)
- {
- var all_width = inst.measureWidth(text);
- if (all_width <= width)
- {
- freeAllLines(lines);
- lines.push(allocLine());
- lines[0].text = text;
- lines[0].width = all_width;
- inst.textWidth = all_width;
- inst.textHeight = inst.characterHeight * charScale + inst.lineHeight;
- return;
- }
- }
- var wrapbyword = inst.wrapbyword;
- this.WrapText(inst);
- inst.textHeight = lines.length * (inst.characterHeight * charScale + inst.lineHeight);
- };
- pluginProto.WrapText = function (inst)
- {
- var wrapbyword = inst.wrapbyword;
- var text = inst.text;
- var lines = inst.lines;
- var width = inst.width;
- var wordArray;
- if (wrapbyword) {
- this.TokeniseWords(text); // writes to wordsCache
- wordArray = wordsCache;
- } else {
- wordArray = text;
- }
- var cur_line = "";
- var prev_line;
- var line_width;
- var i;
- var lineIndex = 0;
- var line;
- var ignore_newline = false;
- for (i = 0; i < wordArray.length; i++)
- {
- if (wordArray[i] === "\n")
- {
- if (ignore_newline === true) {
- ignore_newline = false;
- } else {
- addLine(inst,lineIndex,cur_line);
- lineIndex++;
- }
- cur_line = "";
- continue;
- }
- ignore_newline = false;
- prev_line = cur_line;
- cur_line += wordArray[i];
- line_width = inst.measureWidth(trimRight(cur_line));
- if (line_width > width)
- {
- if (prev_line === "") {
- addLine(inst,lineIndex,cur_line);
- cur_line = "";
- ignore_newline = true;
- } else {
- addLine(inst,lineIndex,prev_line);
- cur_line = wordArray[i];
- }
- lineIndex++;
- if (!wrapbyword && cur_line === " ")
- cur_line = "";
- }
- }
- if (trimRight(cur_line).length)
- {
- addLine(inst,lineIndex,cur_line);
- lineIndex++;
- }
- for (i = lineIndex; i < lines.length; i++)
- freeLine(lines[i]);
- lines.length = lineIndex;
- };
- instanceProto.measureWidth = function(text) {
- var spacing = this.characterSpacing;
- var len = text.length;
- var width = 0;
- for (var i = 0; i < len; i++) {
- width += this.getCharacterWidth(text.charAt(i)) * this.characterScale + spacing;
- }
- width -= (width > 0) ? spacing : 0;
- return width;
- };
- /***/
- instanceProto.getCharacterWidth = function(character) {
- var widthList = this.characterWidthList;
- if (widthList[character] !== undefined) {
- return widthList[character];
- } else {
- return this.characterWidth;
- }
- };
- instanceProto.rebuildText = function() {
- if (this.text_changed || this.width !== this.lastwrapwidth) {
- this.textWidth = 0;
- this.textHeight = 0;
- this.type.plugin.WordWrap(this);
- this.text_changed = false;
- this.lastwrapwidth = this.width;
- }
- };
- var EPSILON = 0.00001;
- instanceProto.draw = function(ctx, glmode)
- {
- var texture = this.texture_img;
- if (this.text !== "" && texture != null) {
- this.rebuildText();
- if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
- return;
- }
- ctx.globalAlpha = this.opacity;
- var myx = this.x;
- var myy = this.y;
- if (this.runtime.pixel_rounding)
- {
- myx = (myx + 0.5) | 0;
- myy = (myy + 0.5) | 0;
- }
- ctx.save();
- ctx.translate(myx, myy);
- ctx.rotate(this.angle);
- var ha = this.halign;
- var va = this.valign;
- var scale = this.characterScale;
- var charHeight = this.characterHeight * scale;
- var lineHeight = this.lineHeight;
- var charSpace = this.characterSpacing;
- var lines = this.lines;
- var textHeight = this.textHeight;
- var halign;
- var valign = va * cr.max(0,(this.height - textHeight));
- var offx = -(this.hotspotX * this.width);
- var offy = -(this.hotspotY * this.height);
- offy += valign;
- var drawX ;
- var drawY = offy;
- for(var i = 0; i < lines.length; i++) {
- var line = lines[i].text;
- var len = lines[i].width;
- halign = ha * cr.max(0,this.width - len);
- drawX = offx + halign;
- drawY += lineHeight;
- for(var j = 0; j < line.length; j++) {
- var letter = line.charAt(j);
- var clip = this.clipList[letter];
- if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON ) {
- break;
- }
- if (clip !== undefined) {
- ctx.drawImage( this.texture_img,
- clip.x, clip.y, clip.w, clip.h,
- Math.round(drawX),Math.round(drawY),clip.w*scale,clip.h*scale);
- }
- drawX += this.getCharacterWidth(letter) * scale + charSpace;
- }
- drawY += charHeight;
- if ( drawY + charHeight + lineHeight > this.height) {
- break;
- }
- }
- ctx.restore();
- }
- };
- var dQuad = new cr.quad();
- function rotateQuad(quad,cosa,sina) {
- var x_temp;
- x_temp = (quad.tlx * cosa) - (quad.tly * sina);
- quad.tly = (quad.tly * cosa) + (quad.tlx * sina);
- quad.tlx = x_temp;
- x_temp = (quad.trx * cosa) - (quad.try_ * sina);
- quad.try_ = (quad.try_ * cosa) + (quad.trx * sina);
- quad.trx = x_temp;
- x_temp = (quad.blx * cosa) - (quad.bly * sina);
- quad.bly = (quad.bly * cosa) + (quad.blx * sina);
- quad.blx = x_temp;
- x_temp = (quad.brx * cosa) - (quad.bry * sina);
- quad.bry = (quad.bry * cosa) + (quad.brx * sina);
- quad.brx = x_temp;
- }
- instanceProto.drawGL = function(glw)
- {
- glw.setTexture(this.webGL_texture);
- glw.setOpacity(this.opacity);
- if (this.text !== "") {
- this.rebuildText();
- if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
- return;
- }
- this.update_bbox();
- var q = this.bquad;
- var ox = 0;
- var oy = 0;
- if (this.runtime.pixel_rounding)
- {
- ox = ((this.x + 0.5) | 0) - this.x;
- oy = ((this.y + 0.5) | 0) - this.y;
- }
- var angle = this.angle;
- var ha = this.halign;
- var va = this.valign;
- var scale = this.characterScale;
- var charHeight = this.characterHeight * scale; // to precalculate in onCreate or on change
- var lineHeight = this.lineHeight;
- var charSpace = this.characterSpacing;
- var lines = this.lines;
- var textHeight = this.textHeight;
- var cosa,sina;
- if (angle !== 0)
- {
- cosa = Math.cos(angle);
- sina = Math.sin(angle);
- }
- var halign;
- var valign = va * cr.max(0,(this.height - textHeight));
- var offx = q.tlx + ox;
- var offy = q.tly + oy;
- var drawX ;
- var drawY = valign;
- for(var i = 0; i < lines.length; i++) {
- var line = lines[i].text;
- var lineWidth = lines[i].width;
- halign = ha * cr.max(0,this.width - lineWidth);
- drawX = halign;
- drawY += lineHeight;
- for(var j = 0; j < line.length; j++) {
- var letter = line.charAt(j);
- var clipUV = this.clipUV[letter];
- if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON) {
- break;
- }
- if (clipUV !== undefined) {
- var clipWidth = this.characterWidth*scale;
- var clipHeight = this.characterHeight*scale;
- dQuad.tlx = drawX;
- dQuad.tly = drawY;
- dQuad.trx = drawX + clipWidth;
- dQuad.try_ = drawY ;
- dQuad.blx = drawX;
- dQuad.bly = drawY + clipHeight;
- dQuad.brx = drawX + clipWidth;
- dQuad.bry = drawY + clipHeight;
- if(angle !== 0)
- {
- rotateQuad(dQuad,cosa,sina);
- }
- dQuad.offset(offx,offy);
- glw.quadTex(
- dQuad.tlx, dQuad.tly,
- dQuad.trx, dQuad.try_,
- dQuad.brx, dQuad.bry,
- dQuad.blx, dQuad.bly,
- clipUV
- );
- }
- drawX += this.getCharacterWidth(letter) * scale + charSpace;
- }
- drawY += charHeight;
- if ( drawY + charHeight + lineHeight > this.height) {
- break;
- }
- }
- }
- };
- function Cnds() {}
- Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
- {
- if (case_sensitive)
- return this.text == text_to_compare;
- else
- return cr.equals_nocase(this.text, text_to_compare);
- };
- pluginProto.cnds = new Cnds();
- function Acts() {}
- Acts.prototype.SetText = function(param)
- {
- if (cr.is_number(param) && param < 1e9)
- param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
- var text_to_set = param.toString();
- if (this.text !== text_to_set)
- {
- this.text = text_to_set;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.AppendText = function(param)
- {
- if (cr.is_number(param))
- param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
- var text_to_append = param.toString();
- if (text_to_append) // not empty
- {
- this.text += text_to_append;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.SetScale = function(param)
- {
- if (param !== this.characterScale) {
- this.characterScale = param;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.SetCharacterSpacing = function(param)
- {
- if (param !== this.CharacterSpacing) {
- this.characterSpacing = param;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.SetLineHeight = function(param)
- {
- if (param !== this.lineHeight) {
- this.lineHeight = param;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- instanceProto.SetCharWidth = function(character,width) {
- var w = parseInt(width,10);
- if (this.characterWidthList[character] !== w) {
- this.characterWidthList[character] = w;
- this.text_changed = true;
- this.runtime.redraw = true;
- }
- };
- Acts.prototype.SetCharacterWidth = function(characterSet,width)
- {
- if (characterSet !== "") {
- for(var c = 0; c < characterSet.length; c++) {
- this.SetCharWidth(characterSet.charAt(c),width);
- }
- }
- };
- Acts.prototype.SetEffect = function (effect)
- {
- this.compositeOp = cr.effectToCompositeOp(effect);
- cr.setGLBlend(this, effect, this.runtime.gl);
- this.runtime.redraw = true;
- };
- pluginProto.acts = new Acts();
- function Exps() {}
- Exps.prototype.CharacterWidth = function(ret,character)
- {
- ret.set_int(this.getCharacterWidth(character));
- };
- Exps.prototype.CharacterHeight = function(ret)
- {
- ret.set_int(this.characterHeight);
- };
- Exps.prototype.CharacterScale = function(ret)
- {
- ret.set_float(this.characterScale);
- };
- Exps.prototype.CharacterSpacing = function(ret)
- {
- ret.set_int(this.characterSpacing);
- };
- Exps.prototype.LineHeight = function(ret)
- {
- ret.set_int(this.lineHeight);
- };
- Exps.prototype.Text = function(ret)
- {
- ret.set_string(this.text);
- };
- Exps.prototype.TextWidth = function (ret)
- {
- this.rebuildText();
- ret.set_float(this.textWidth);
- };
- Exps.prototype.TextHeight = function (ret)
- {
- this.rebuildText();
- ret.set_float(this.textHeight);
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.plugins_.Touch = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var pluginProto = cr.plugins_.Touch.prototype;
- pluginProto.Type = function(plugin)
- {
- this.plugin = plugin;
- this.runtime = plugin.runtime;
- };
- var typeProto = pluginProto.Type.prototype;
- typeProto.onCreate = function()
- {
- };
- pluginProto.Instance = function(type)
- {
- this.type = type;
- this.runtime = type.runtime;
- this.touches = [];
- this.mouseDown = false;
- };
- var instanceProto = pluginProto.Instance.prototype;
- var dummyoffset = {left: 0, top: 0};
- instanceProto.findTouch = function (id)
- {
- var i, len;
- for (i = 0, len = this.touches.length; i < len; i++)
- {
- if (this.touches[i]["id"] === id)
- return i;
- }
- return -1;
- };
- var appmobi_accx = 0;
- var appmobi_accy = 0;
- var appmobi_accz = 0;
- function AppMobiGetAcceleration(evt)
- {
- appmobi_accx = evt.x;
- appmobi_accy = evt.y;
- appmobi_accz = evt.z;
- };
- var pg_accx = 0;
- var pg_accy = 0;
- var pg_accz = 0;
- function PhoneGapGetAcceleration(evt)
- {
- pg_accx = evt.x;
- pg_accy = evt.y;
- pg_accz = evt.z;
- };
- var theInstance = null;
- var touchinfo_cache = [];
- function AllocTouchInfo(x, y, id, index)
- {
- var ret;
- if (touchinfo_cache.length)
- ret = touchinfo_cache.pop();
- else
- ret = new TouchInfo();
- ret.init(x, y, id, index);
- return ret;
- };
- function ReleaseTouchInfo(ti)
- {
- if (touchinfo_cache.length < 100)
- touchinfo_cache.push(ti);
- };
- var GESTURE_HOLD_THRESHOLD = 15; // max px motion for hold gesture to register
- var GESTURE_HOLD_TIMEOUT = 500; // time for hold gesture to register
- var GESTURE_TAP_TIMEOUT = 333; // time for tap gesture to register
- var GESTURE_DOUBLETAP_THRESHOLD = 25; // max distance apart for taps to be
- function TouchInfo()
- {
- this.starttime = 0;
- this.time = 0;
- this.lasttime = 0;
- this.startx = 0;
- this.starty = 0;
- this.x = 0;
- this.y = 0;
- this.lastx = 0;
- this.lasty = 0;
- this["id"] = 0;
- this.startindex = 0;
- this.triggeredHold = false;
- this.tooFarForHold = false;
- };
- TouchInfo.prototype.init = function (x, y, id, index)
- {
- var nowtime = cr.performance_now();
- this.time = nowtime;
- this.lasttime = nowtime;
- this.starttime = nowtime;
- this.startx = x;
- this.starty = y;
- this.x = x;
- this.y = y;
- this.lastx = x;
- this.lasty = y;
- this.width = 0;
- this.height = 0;
- this.pressure = 0;
- this["id"] = id;
- this.startindex = index;
- this.triggeredHold = false;
- this.tooFarForHold = false;
- };
- TouchInfo.prototype.update = function (nowtime, x, y, width, height, pressure)
- {
- this.lasttime = this.time;
- this.time = nowtime;
- this.lastx = this.x;
- this.lasty = this.y;
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- this.pressure = pressure;
- if (!this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) >= GESTURE_HOLD_THRESHOLD)
- {
- this.tooFarForHold = true;
- }
- };
- TouchInfo.prototype.maybeTriggerHold = function (inst, index)
- {
- if (this.triggeredHold)
- return; // already triggered this gesture
- var nowtime = cr.performance_now();
- if (nowtime - this.starttime >= GESTURE_HOLD_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
- {
- this.triggeredHold = true;
- inst.trigger_index = this.startindex;
- inst.trigger_id = this["id"];
- inst.getTouchIndex = index;
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGesture, inst);
- inst.curTouchX = this.x;
- inst.curTouchY = this.y;
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGestureObject, inst);
- inst.getTouchIndex = 0;
- }
- };
- var lastTapX = -1000;
- var lastTapY = -1000;
- var lastTapTime = -10000;
- TouchInfo.prototype.maybeTriggerTap = function (inst, index)
- {
- if (this.triggeredHold)
- return;
- var nowtime = cr.performance_now();
- if (nowtime - this.starttime <= GESTURE_TAP_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
- {
- inst.trigger_index = this.startindex;
- inst.trigger_id = this["id"];
- inst.getTouchIndex = index;
- if ((nowtime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2) && cr.distanceTo(lastTapX, lastTapY, this.x, this.y) < GESTURE_DOUBLETAP_THRESHOLD)
- {
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGesture, inst);
- inst.curTouchX = this.x;
- inst.curTouchY = this.y;
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGestureObject, inst);
- lastTapX = -1000;
- lastTapY = -1000;
- lastTapTime = -10000;
- }
- else
- {
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGesture, inst);
- inst.curTouchX = this.x;
- inst.curTouchY = this.y;
- inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGestureObject, inst);
- lastTapX = this.x;
- lastTapY = this.y;
- lastTapTime = nowtime;
- }
- inst.getTouchIndex = 0;
- }
- };
- instanceProto.onCreate = function()
- {
- theInstance = this;
- this.isWindows8 = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
- this.orient_alpha = 0;
- this.orient_beta = 0;
- this.orient_gamma = 0;
- this.acc_g_x = 0;
- this.acc_g_y = 0;
- this.acc_g_z = 0;
- this.acc_x = 0;
- this.acc_y = 0;
- this.acc_z = 0;
- this.curTouchX = 0;
- this.curTouchY = 0;
- this.trigger_index = 0;
- this.trigger_id = 0;
- this.trigger_permission = 0;
- this.getTouchIndex = 0;
- this.useMouseInput = (this.properties[0] !== 0);
- var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
- var elem2 = document;
- if (this.runtime.isDirectCanvas)
- elem2 = elem = window["Canvas"];
- else if (this.runtime.isCocoonJs)
- elem2 = elem = window;
- var self = this;
- if (typeof PointerEvent !== "undefined")
- {
- elem.addEventListener("pointerdown",
- function(info) {
- self.onPointerStart(info);
- },
- false
- );
- elem.addEventListener("pointermove",
- function(info) {
- self.onPointerMove(info);
- },
- false
- );
- elem2.addEventListener("pointerup",
- function(info) {
- self.onPointerEnd(info, false);
- },
- false
- );
- elem2.addEventListener("pointercancel",
- function(info) {
- self.onPointerEnd(info, true);
- },
- false
- );
- if (this.runtime.canvas)
- {
- this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
- e.preventDefault();
- }, false);
- document.addEventListener("MSGestureHold", function(e) {
- e.preventDefault();
- }, false);
- this.runtime.canvas.addEventListener("gesturehold", function(e) {
- e.preventDefault();
- }, false);
- document.addEventListener("gesturehold", function(e) {
- e.preventDefault();
- }, false);
- }
- }
- else if (window.navigator["msPointerEnabled"])
- {
- elem.addEventListener("MSPointerDown",
- function(info) {
- self.onPointerStart(info);
- },
- false
- );
- elem.addEventListener("MSPointerMove",
- function(info) {
- self.onPointerMove(info);
- },
- false
- );
- elem2.addEventListener("MSPointerUp",
- function(info) {
- self.onPointerEnd(info, false);
- },
- false
- );
- elem2.addEventListener("MSPointerCancel",
- function(info) {
- self.onPointerEnd(info, true);
- },
- false
- );
- if (this.runtime.canvas)
- {
- this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
- e.preventDefault();
- }, false);
- document.addEventListener("MSGestureHold", function(e) {
- e.preventDefault();
- }, false);
- }
- }
- else
- {
- elem.addEventListener("touchstart",
- function(info) {
- self.onTouchStart(info);
- },
- false
- );
- elem.addEventListener("touchmove",
- function(info) {
- self.onTouchMove(info);
- },
- false
- );
- elem2.addEventListener("touchend",
- function(info) {
- self.onTouchEnd(info, false);
- },
- false
- );
- elem2.addEventListener("touchcancel",
- function(info) {
- self.onTouchEnd(info, true);
- },
- false
- );
- }
- if (this.isWindows8)
- {
- var win8accelerometerFn = function(e) {
- var reading = e["reading"];
- self.acc_x = reading["accelerationX"];
- self.acc_y = reading["accelerationY"];
- self.acc_z = reading["accelerationZ"];
- };
- var win8inclinometerFn = function(e) {
- var reading = e["reading"];
- self.orient_alpha = reading["yawDegrees"];
- self.orient_beta = reading["pitchDegrees"];
- self.orient_gamma = reading["rollDegrees"];
- };
- var accelerometer = Windows["Devices"]["Sensors"]["Accelerometer"]["getDefault"]();
- if (accelerometer)
- {
- accelerometer["reportInterval"] = Math.max(accelerometer["minimumReportInterval"], 16);
- accelerometer.addEventListener("readingchanged", win8accelerometerFn);
- }
- var inclinometer = Windows["Devices"]["Sensors"]["Inclinometer"]["getDefault"]();
- if (inclinometer)
- {
- inclinometer["reportInterval"] = Math.max(inclinometer["minimumReportInterval"], 16);
- inclinometer.addEventListener("readingchanged", win8inclinometerFn);
- }
- document.addEventListener("visibilitychange", function(e) {
- if (document["hidden"] || document["msHidden"])
- {
- if (accelerometer)
- accelerometer.removeEventListener("readingchanged", win8accelerometerFn);
- if (inclinometer)
- inclinometer.removeEventListener("readingchanged", win8inclinometerFn);
- }
- else
- {
- if (accelerometer)
- accelerometer.addEventListener("readingchanged", win8accelerometerFn);
- if (inclinometer)
- inclinometer.addEventListener("readingchanged", win8inclinometerFn);
- }
- }, false);
- }
- else
- {
- window.addEventListener("deviceorientation", function (eventData) {
- self.orient_alpha = eventData["alpha"] || 0;
- self.orient_beta = eventData["beta"] || 0;
- self.orient_gamma = eventData["gamma"] || 0;
- }, false);
- window.addEventListener("devicemotion", function (eventData) {
- if (eventData["accelerationIncludingGravity"])
- {
- self.acc_g_x = eventData["accelerationIncludingGravity"]["x"] || 0;
- self.acc_g_y = eventData["accelerationIncludingGravity"]["y"] || 0;
- self.acc_g_z = eventData["accelerationIncludingGravity"]["z"] || 0;
- }
- if (eventData["acceleration"])
- {
- self.acc_x = eventData["acceleration"]["x"] || 0;
- self.acc_y = eventData["acceleration"]["y"] || 0;
- self.acc_z = eventData["acceleration"]["z"] || 0;
- }
- }, false);
- }
- if (this.useMouseInput && !this.runtime.isDomFree)
- {
- jQuery(document).mousemove(
- function(info) {
- self.onMouseMove(info);
- }
- );
- jQuery(document).mousedown(
- function(info) {
- self.onMouseDown(info);
- }
- );
- jQuery(document).mouseup(
- function(info) {
- self.onMouseUp(info);
- }
- );
- }
- if (!this.runtime.isiOS && this.runtime.isCordova && navigator["accelerometer"] && navigator["accelerometer"]["watchAcceleration"])
- {
- navigator["accelerometer"]["watchAcceleration"](PhoneGapGetAcceleration, null, { "frequency": 40 });
- }
- this.runtime.tick2Me(this);
- };
- instanceProto.onPointerMove = function (info)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault)
- info.preventDefault();
- var i = this.findTouch(info["pointerId"]);
- var nowtime = cr.performance_now();
- if (i >= 0)
- {
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- var t = this.touches[i];
- if (nowtime - t.time < 2)
- return;
- t.update(nowtime, info.pageX - offset.left, info.pageY - offset.top, info.width || 0, info.height || 0, info.pressure || 0);
- }
- };
- instanceProto.onPointerStart = function (info)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- var touchx = info.pageX - offset.left;
- var touchy = info.pageY - offset.top;
- var nowtime = cr.performance_now();
- this.trigger_index = this.touches.length;
- this.trigger_id = info["pointerId"];
- this.touches.push(AllocTouchInfo(touchx, touchy, info["pointerId"], this.trigger_index));
- this.runtime.isInUserInputEvent = true;
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
- this.curTouchX = touchx;
- this.curTouchY = touchy;
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
- this.runtime.isInUserInputEvent = false;
- };
- instanceProto.onPointerEnd = function (info, isCancel)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- var i = this.findTouch(info["pointerId"]);
- this.trigger_index = (i >= 0 ? this.touches[i].startindex : -1);
- this.trigger_id = (i >= 0 ? this.touches[i]["id"] : -1);
- this.runtime.isInUserInputEvent = true;
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
- if (i >= 0)
- {
- if (!isCancel)
- this.touches[i].maybeTriggerTap(this, i);
- ReleaseTouchInfo(this.touches[i]);
- this.touches.splice(i, 1);
- }
- this.runtime.isInUserInputEvent = false;
- };
- instanceProto.onTouchMove = function (info)
- {
- if (info.preventDefault)
- info.preventDefault();
- var nowtime = cr.performance_now();
- var i, len, t, u;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- var j = this.findTouch(t["identifier"]);
- if (j >= 0)
- {
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- u = this.touches[j];
- if (nowtime - u.time < 2)
- continue;
- var touchWidth = (t.radiusX || t.webkitRadiusX || t.mozRadiusX || t.msRadiusX || 0) * 2;
- var touchHeight = (t.radiusY || t.webkitRadiusY || t.mozRadiusY || t.msRadiusY || 0) * 2;
- var touchForce = t.force || t.webkitForce || t.mozForce || t.msForce || 0;
- u.update(nowtime, t.pageX - offset.left, t.pageY - offset.top, touchWidth, touchHeight, touchForce);
- }
- }
- };
- instanceProto.onTouchStart = function (info)
- {
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- var nowtime = cr.performance_now();
- this.runtime.isInUserInputEvent = true;
- var i, len, t, j;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- j = this.findTouch(t["identifier"]);
- if (j !== -1)
- continue;
- var touchx = t.pageX - offset.left;
- var touchy = t.pageY - offset.top;
- this.trigger_index = this.touches.length;
- this.trigger_id = t["identifier"];
- this.touches.push(AllocTouchInfo(touchx, touchy, t["identifier"], this.trigger_index));
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
- this.curTouchX = touchx;
- this.curTouchY = touchy;
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
- }
- this.runtime.isInUserInputEvent = false;
- };
- instanceProto.onTouchEnd = function (info, isCancel)
- {
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- this.runtime.isInUserInputEvent = true;
- var i, len, t, j;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- j = this.findTouch(t["identifier"]);
- if (j >= 0)
- {
- this.trigger_index = this.touches[j].startindex;
- this.trigger_id = this.touches[j]["id"];
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
- this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
- if (!isCancel)
- this.touches[j].maybeTriggerTap(this, j);
- ReleaseTouchInfo(this.touches[j]);
- this.touches.splice(j, 1);
- }
- }
- this.runtime.isInUserInputEvent = false;
- };
- instanceProto.getAlpha = function ()
- {
- if (this.runtime.isCordova && this.orient_alpha === 0 && pg_accz !== 0)
- return pg_accz * 90;
- else
- return this.orient_alpha;
- };
- instanceProto.getBeta = function ()
- {
- if (this.runtime.isCordova && this.orient_beta === 0 && pg_accy !== 0)
- return pg_accy * 90;
- else
- return this.orient_beta;
- };
- instanceProto.getGamma = function ()
- {
- if (this.runtime.isCordova && this.orient_gamma === 0 && pg_accx !== 0)
- return pg_accx * 90;
- else
- return this.orient_gamma;
- };
- var noop_func = function(){};
- function isCompatibilityMouseEvent(e)
- {
- return (e["sourceCapabilities"] && e["sourceCapabilities"]["firesTouchEvents"]) ||
- (e.originalEvent && e.originalEvent["sourceCapabilities"] && e.originalEvent["sourceCapabilities"]["firesTouchEvents"]);
- };
- instanceProto.onMouseDown = function(info)
- {
- if (isCompatibilityMouseEvent(info))
- return;
- var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
- var fakeinfo = { changedTouches: [t] };
- this.onTouchStart(fakeinfo);
- this.mouseDown = true;
- };
- instanceProto.onMouseMove = function(info)
- {
- if (!this.mouseDown)
- return;
- if (isCompatibilityMouseEvent(info))
- return;
- var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
- var fakeinfo = { changedTouches: [t] };
- this.onTouchMove(fakeinfo);
- };
- instanceProto.onMouseUp = function(info)
- {
- if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
- info.preventDefault();
- this.runtime.had_a_click = true;
- if (isCompatibilityMouseEvent(info))
- return;
- var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
- var fakeinfo = { changedTouches: [t] };
- this.onTouchEnd(fakeinfo);
- this.mouseDown = false;
- };
- instanceProto.tick2 = function()
- {
- var i, len, t;
- var nowtime = cr.performance_now();
- for (i = 0, len = this.touches.length; i < len; ++i)
- {
- t = this.touches[i];
- if (t.time <= nowtime - 50)
- t.lasttime = nowtime;
- t.maybeTriggerHold(this, i);
- }
- };
- function Cnds() {};
- Cnds.prototype.OnTouchStart = function ()
- {
- return true;
- };
- Cnds.prototype.OnTouchEnd = function ()
- {
- return true;
- };
- Cnds.prototype.IsInTouch = function ()
- {
- return this.touches.length;
- };
- Cnds.prototype.OnTouchObject = function (type)
- {
- if (!type)
- return false;
- return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
- };
- var touching = [];
- Cnds.prototype.IsTouchingObject = function (type)
- {
- if (!type)
- return false;
- var sol = type.getCurrentSol();
- var instances = sol.getObjects();
- var px, py;
- var i, leni, j, lenj;
- for (i = 0, leni = instances.length; i < leni; i++)
- {
- var inst = instances[i];
- inst.update_bbox();
- for (j = 0, lenj = this.touches.length; j < lenj; j++)
- {
- var touch = this.touches[j];
- px = inst.layer.canvasToLayer(touch.x, touch.y, true);
- py = inst.layer.canvasToLayer(touch.x, touch.y, false);
- if (inst.contains_pt(px, py))
- {
- touching.push(inst);
- break;
- }
- }
- }
- if (touching.length)
- {
- sol.select_all = false;
- cr.shallowAssignArray(sol.instances, touching);
- type.applySolToContainer();
- cr.clearArray(touching);
- return true;
- }
- else
- return false;
- };
- Cnds.prototype.CompareTouchSpeed = function (index, cmp, s)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- return false;
- var t = this.touches[index];
- var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
- var timediff = (t.time - t.lasttime) / 1000;
- var speed = 0;
- if (timediff > 0)
- speed = dist / timediff;
- return cr.do_cmp(speed, cmp, s);
- };
- Cnds.prototype.OrientationSupported = function ()
- {
- return typeof window["DeviceOrientationEvent"] !== "undefined";
- };
- Cnds.prototype.MotionSupported = function ()
- {
- return typeof window["DeviceMotionEvent"] !== "undefined";
- };
- Cnds.prototype.CompareOrientation = function (orientation_, cmp_, angle_)
- {
- var v = 0;
- if (orientation_ === 0)
- v = this.getAlpha();
- else if (orientation_ === 1)
- v = this.getBeta();
- else
- v = this.getGamma();
- return cr.do_cmp(v, cmp_, angle_);
- };
- Cnds.prototype.CompareAcceleration = function (acceleration_, cmp_, angle_)
- {
- var v = 0;
- if (acceleration_ === 0)
- v = this.acc_g_x;
- else if (acceleration_ === 1)
- v = this.acc_g_y;
- else if (acceleration_ === 2)
- v = this.acc_g_z;
- else if (acceleration_ === 3)
- v = this.acc_x;
- else if (acceleration_ === 4)
- v = this.acc_y;
- else if (acceleration_ === 5)
- v = this.acc_z;
- return cr.do_cmp(v, cmp_, angle_);
- };
- Cnds.prototype.OnNthTouchStart = function (touch_)
- {
- touch_ = Math.floor(touch_);
- return touch_ === this.trigger_index;
- };
- Cnds.prototype.OnNthTouchEnd = function (touch_)
- {
- touch_ = Math.floor(touch_);
- return touch_ === this.trigger_index;
- };
- Cnds.prototype.HasNthTouch = function (touch_)
- {
- touch_ = Math.floor(touch_);
- return this.touches.length >= touch_ + 1;
- };
- Cnds.prototype.OnHoldGesture = function ()
- {
- return true;
- };
- Cnds.prototype.OnTapGesture = function ()
- {
- return true;
- };
- Cnds.prototype.OnDoubleTapGesture = function ()
- {
- return true;
- };
- Cnds.prototype.OnHoldGestureObject = function (type)
- {
- if (!type)
- return false;
- return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
- };
- Cnds.prototype.OnTapGestureObject = function (type)
- {
- if (!type)
- return false;
- return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
- };
- Cnds.prototype.OnDoubleTapGestureObject = function (type)
- {
- if (!type)
- return false;
- return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
- };
- Cnds.prototype.OnPermissionGranted = function (type)
- {
- return this.trigger_permission === type;
- };
- Cnds.prototype.OnPermissionDenied = function (type)
- {
- return this.trigger_permission === type;
- };
- pluginProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.RequestPermission = function (type)
- {
- var self = this;
- var promise = Promise.resolve(true);
- if (type === 0) // orientation
- {
- if (window["DeviceOrientationEvent"] && window["DeviceOrientationEvent"]["requestPermission"])
- {
- promise = window["DeviceOrientationEvent"]["requestPermission"]()
- .then(function (state)
- {
- return state === "granted";
- });
- }
- }
- else // motion
- {
- if (window["DeviceMotionEvent"] && window["DeviceMotionEvent"]["requestPermission"])
- {
- promise = window["DeviceMotionEvent"]["requestPermission"]()
- .then(function (state)
- {
- return state === "granted";
- });
- }
- }
- promise.then(function (result)
- {
- self.trigger_permission = type;
- if (result)
- self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionGranted, self);
- else
- self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionDenied, self);
- });
- };
- pluginProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.TouchCount = function (ret)
- {
- ret.set_int(this.touches.length);
- };
- Exps.prototype.X = function (ret, layerparam)
- {
- var index = this.getTouchIndex;
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxX = layer.parallaxX;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxX = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxX = oldParallaxX;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.XAt = function (ret, index, layerparam)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxX = layer.parallaxX;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxX = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxX = oldParallaxX;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.XForID = function (ret, id, layerparam)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxX = layer.parallaxX;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxX = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxX = oldParallaxX;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.Y = function (ret, layerparam)
- {
- var index = this.getTouchIndex;
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxY = layer.parallaxY;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxY = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxY = oldParallaxY;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.YAt = function (ret, index, layerparam)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxY = layer.parallaxY;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxY = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxY = oldParallaxY;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.YForID = function (ret, id, layerparam)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
- if (cr.is_undefined(layerparam))
- {
- layer = this.runtime.getLayerByNumber(0);
- oldScale = layer.scale;
- oldZoomRate = layer.zoomRate;
- oldParallaxY = layer.parallaxY;
- oldAngle = layer.angle;
- layer.scale = 1;
- layer.zoomRate = 1.0;
- layer.parallaxY = 1.0;
- layer.angle = 0;
- ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
- layer.scale = oldScale;
- layer.zoomRate = oldZoomRate;
- layer.parallaxY = oldParallaxY;
- layer.angle = oldAngle;
- }
- else
- {
- if (cr.is_number(layerparam))
- layer = this.runtime.getLayerByNumber(layerparam);
- else
- layer = this.runtime.getLayerByName(layerparam);
- if (layer)
- ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
- else
- ret.set_float(0);
- }
- };
- Exps.prototype.AbsoluteX = function (ret)
- {
- if (this.touches.length)
- ret.set_float(this.touches[0].x);
- else
- ret.set_float(0);
- };
- Exps.prototype.AbsoluteXAt = function (ret, index)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- ret.set_float(this.touches[index].x);
- };
- Exps.prototype.AbsoluteXForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(touch.x);
- };
- Exps.prototype.AbsoluteY = function (ret)
- {
- if (this.touches.length)
- ret.set_float(this.touches[0].y);
- else
- ret.set_float(0);
- };
- Exps.prototype.AbsoluteYAt = function (ret, index)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- ret.set_float(this.touches[index].y);
- };
- Exps.prototype.AbsoluteYForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(touch.y);
- };
- Exps.prototype.SpeedAt = function (ret, index)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var t = this.touches[index];
- var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
- var timediff = (t.time - t.lasttime) / 1000;
- if (timediff <= 0)
- ret.set_float(0);
- else
- ret.set_float(dist / timediff);
- };
- Exps.prototype.SpeedForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- var dist = cr.distanceTo(touch.x, touch.y, touch.lastx, touch.lasty);
- var timediff = (touch.time - touch.lasttime) / 1000;
- if (timediff <= 0)
- ret.set_float(0);
- else
- ret.set_float(dist / timediff);
- };
- Exps.prototype.AngleAt = function (ret, index)
- {
- index = Math.floor(index);
- if (index < 0 || index >= this.touches.length)
- {
- ret.set_float(0);
- return;
- }
- var t = this.touches[index];
- ret.set_float(cr.to_degrees(cr.angleTo(t.lastx, t.lasty, t.x, t.y)));
- };
- Exps.prototype.AngleForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(cr.to_degrees(cr.angleTo(touch.lastx, touch.lasty, touch.x, touch.y)));
- };
- Exps.prototype.Alpha = function (ret)
- {
- ret.set_float(this.getAlpha());
- };
- Exps.prototype.Beta = function (ret)
- {
- ret.set_float(this.getBeta());
- };
- Exps.prototype.Gamma = function (ret)
- {
- ret.set_float(this.getGamma());
- };
- Exps.prototype.AccelerationXWithG = function (ret)
- {
- ret.set_float(this.acc_g_x);
- };
- Exps.prototype.AccelerationYWithG = function (ret)
- {
- ret.set_float(this.acc_g_y);
- };
- Exps.prototype.AccelerationZWithG = function (ret)
- {
- ret.set_float(this.acc_g_z);
- };
- Exps.prototype.AccelerationX = function (ret)
- {
- ret.set_float(this.acc_x);
- };
- Exps.prototype.AccelerationY = function (ret)
- {
- ret.set_float(this.acc_y);
- };
- Exps.prototype.AccelerationZ = function (ret)
- {
- ret.set_float(this.acc_z);
- };
- Exps.prototype.TouchIndex = function (ret)
- {
- ret.set_int(this.trigger_index);
- };
- Exps.prototype.TouchID = function (ret)
- {
- ret.set_float(this.trigger_id);
- };
- Exps.prototype.WidthForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(touch.width);
- };
- Exps.prototype.HeightForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(touch.height);
- };
- Exps.prototype.PressureForID = function (ret, id)
- {
- var index = this.findTouch(id);
- if (index < 0)
- {
- ret.set_float(0);
- return;
- }
- var touch = this.touches[index];
- ret.set_float(touch.pressure);
- };
- pluginProto.exps = new Exps();
-}());
-;
-;
-cr.behaviors.DragnDrop = function(runtime)
-{
- this.runtime = runtime;
- var self = this;
- if (!this.runtime.isDomFree)
- {
- jQuery(document).mousemove(
- function(info) {
- self.onMouseMove(info);
- }
- );
- jQuery(document).mousedown(
- function(info) {
- self.onMouseDown(info);
- }
- );
- jQuery(document).mouseup(
- function(info) {
- self.onMouseUp(info);
- }
- );
- }
- var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
- if (this.runtime.isDirectCanvas)
- elem = window["Canvas"];
- else if (this.runtime.isCocoonJs)
- elem = window;
- if (typeof PointerEvent !== "undefined")
- {
- elem.addEventListener("pointerdown",
- function(info) {
- self.onPointerStart(info);
- },
- false
- );
- elem.addEventListener("pointermove",
- function(info) {
- self.onPointerMove(info);
- },
- false
- );
- elem.addEventListener("pointerup",
- function(info) {
- self.onPointerEnd(info);
- },
- false
- );
- elem.addEventListener("pointercancel",
- function(info) {
- self.onPointerEnd(info);
- },
- false
- );
- }
- else if (window.navigator["msPointerEnabled"])
- {
- elem.addEventListener("MSPointerDown",
- function(info) {
- self.onPointerStart(info);
- },
- false
- );
- elem.addEventListener("MSPointerMove",
- function(info) {
- self.onPointerMove(info);
- },
- false
- );
- elem.addEventListener("MSPointerUp",
- function(info) {
- self.onPointerEnd(info);
- },
- false
- );
- elem.addEventListener("MSPointerCancel",
- function(info) {
- self.onPointerEnd(info);
- },
- false
- );
- }
- else
- {
- elem.addEventListener("touchstart",
- function(info) {
- self.onTouchStart(info);
- },
- false
- );
- elem.addEventListener("touchmove",
- function(info) {
- self.onTouchMove(info);
- },
- false
- );
- elem.addEventListener("touchend",
- function(info) {
- self.onTouchEnd(info);
- },
- false
- );
- elem.addEventListener("touchcancel",
- function(info) {
- self.onTouchEnd(info);
- },
- false
- );
- }
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.DragnDrop.prototype;
- var dummyoffset = {left: 0, top: 0};
- function GetDragDropBehavior(inst)
- {
- var i, len;
- for (i = 0, len = inst.behavior_insts.length; i < len; i++)
- {
- if (inst.behavior_insts[i] instanceof behaviorProto.Instance)
- return inst.behavior_insts[i];
- }
- return null;
- };
- behaviorProto.onMouseDown = function (info)
- {
- if (info.which !== 1)
- return; // not left mouse button
- this.onInputDown("leftmouse", info.pageX, info.pageY);
- };
- behaviorProto.onMouseMove = function (info)
- {
- if (info.which !== 1)
- return; // not left mouse button
- this.onInputMove("leftmouse", info.pageX, info.pageY);
- };
- behaviorProto.onMouseUp = function (info)
- {
- if (info.which !== 1)
- return; // not left mouse button
- this.onInputUp("leftmouse");
- };
- behaviorProto.onTouchStart = function (info)
- {
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- var i, len, t, id;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- id = t.identifier;
- this.onInputDown(id ? id.toString() : "", t.pageX, t.pageY);
- }
- };
- behaviorProto.onTouchMove = function (info)
- {
- if (info.preventDefault)
- info.preventDefault();
- var i, len, t, id;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- id = t.identifier;
- this.onInputMove(id ? id.toString() : "", t.pageX, t.pageY);
- }
- };
- behaviorProto.onTouchEnd = function (info)
- {
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- var i, len, t, id;
- for (i = 0, len = info.changedTouches.length; i < len; i++)
- {
- t = info.changedTouches[i];
- id = t.identifier;
- this.onInputUp(id ? id.toString() : "");
- }
- };
- behaviorProto.onPointerStart = function (info)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- this.onInputDown(info["pointerId"].toString(), info.pageX, info.pageY);
- };
- behaviorProto.onPointerMove = function (info)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault)
- info.preventDefault();
- this.onInputMove(info["pointerId"].toString(), info.pageX, info.pageY);
- };
- behaviorProto.onPointerEnd = function (info)
- {
- if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
- return;
- if (info.preventDefault && cr.isCanvasInputEvent(info))
- info.preventDefault();
- this.onInputUp(info["pointerId"].toString());
- };
- behaviorProto.onInputDown = function (src, pageX, pageY)
- {
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- var x = pageX - offset.left;
- var y = pageY - offset.top;
- var lx, ly, topx, topy;
- var arr = this.my_instances.valuesRef();
- var i, len, b, inst, topmost = null;
- for (i = 0, len = arr.length; i < len; i++)
- {
- inst = arr[i];
- b = GetDragDropBehavior(inst);
- if (!b.enabled || b.dragging)
- continue; // don't consider disabled or already-dragging instances
- lx = inst.layer.canvasToLayer(x, y, true);
- ly = inst.layer.canvasToLayer(x, y, false);
- inst.update_bbox();
- if (!inst.contains_pt(lx, ly))
- continue; // don't consider instances not over this point
- if (!topmost)
- {
- topmost = inst;
- topx = lx;
- topy = ly;
- continue;
- }
- if (inst.layer.index > topmost.layer.index)
- {
- topmost = inst;
- topx = lx;
- topy = ly;
- continue;
- }
- if (inst.layer.index === topmost.layer.index && inst.get_zindex() > topmost.get_zindex())
- {
- topmost = inst;
- topx = lx;
- topy = ly;
- continue;
- }
- }
- if (topmost)
- GetDragDropBehavior(topmost).onDown(src, topx, topy);
- };
- behaviorProto.onInputMove = function (src, pageX, pageY)
- {
- var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
- var x = pageX - offset.left;
- var y = pageY - offset.top;
- var lx, ly;
- var arr = this.my_instances.valuesRef();
- var i, len, b, inst;
- for (i = 0, len = arr.length; i < len; i++)
- {
- inst = arr[i];
- b = GetDragDropBehavior(inst);
- if (!b.enabled || !b.dragging || (b.dragging && b.dragsource !== src))
- continue; // don't consider disabled, not-dragging, or dragging by other sources
- lx = inst.layer.canvasToLayer(x, y, true);
- ly = inst.layer.canvasToLayer(x, y, false);
- b.onMove(lx, ly);
- }
- };
- behaviorProto.onInputUp = function (src)
- {
- var arr = this.my_instances.valuesRef();
- var i, len, b, inst;
- for (i = 0, len = arr.length; i < len; i++)
- {
- inst = arr[i];
- b = GetDragDropBehavior(inst);
- if (b.dragging && b.dragsource === src)
- b.onUp();
- }
- };
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- };
- var behinstProto = behaviorProto.Instance.prototype;
- behinstProto.onCreate = function()
- {
- this.dragging = false;
- this.dx = 0;
- this.dy = 0;
- this.dragsource = "";
- this.axes = this.properties[0];
- this.enabled = (this.properties[1] !== 0);
- };
- behinstProto.saveToJSON = function ()
- {
- return { "enabled": this.enabled };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.enabled = o["enabled"];
- this.dragging = false;
- };
- behinstProto.onDown = function(src, x, y)
- {
- this.dx = x - this.inst.x;
- this.dy = y - this.inst.y;
- this.dragging = true;
- this.dragsource = src;
- this.runtime.isInUserInputEvent = true;
- this.runtime.trigger(cr.behaviors.DragnDrop.prototype.cnds.OnDragStart, this.inst);
- this.runtime.isInUserInputEvent = false;
- };
- behinstProto.onMove = function(x, y)
- {
- var newx = x - this.dx;
- var newy = y - this.dy;
- if (this.axes === 0) // both
- {
- if (this.inst.x !== newx || this.inst.y !== newy)
- {
- this.inst.x = newx;
- this.inst.y = newy;
- this.inst.set_bbox_changed();
- }
- }
- else if (this.axes === 1) // horizontal
- {
- if (this.inst.x !== newx)
- {
- this.inst.x = newx;
- this.inst.set_bbox_changed();
- }
- }
- else if (this.axes === 2) // vertical
- {
- if (this.inst.y !== newy)
- {
- this.inst.y = newy;
- this.inst.set_bbox_changed();
- }
- }
- };
- behinstProto.onUp = function()
- {
- this.dragging = false;
- this.runtime.isInUserInputEvent = true;
- this.runtime.trigger(cr.behaviors.DragnDrop.prototype.cnds.OnDrop, this.inst);
- this.runtime.isInUserInputEvent = false;
- };
- behinstProto.tick = function ()
- {
- };
- function Cnds() {};
- Cnds.prototype.IsDragging = function ()
- {
- return this.dragging;
- };
- Cnds.prototype.OnDragStart = function ()
- {
- return true;
- };
- Cnds.prototype.OnDrop = function ()
- {
- return true;
- };
- Cnds.prototype.IsEnabled = function ()
- {
- return !!this.enabled;
- };
- behaviorProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.SetEnabled = function (s)
- {
- this.enabled = (s !== 0);
- if (!this.enabled)
- this.dragging = false;
- };
- Acts.prototype.Drop = function ()
- {
- if (this.dragging)
- this.onUp();
- };
- behaviorProto.acts = new Acts();
- function Exps() {};
- behaviorProto.exps = new Exps();
-}());
-;
-;
-cr.behaviors.Fade = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.Fade.prototype;
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- };
- var behinstProto = behaviorProto.Instance.prototype;
- behinstProto.onCreate = function()
- {
- this.activeAtStart = this.properties[0] === 1;
- this.setMaxOpacity = false; // used to retrieve maxOpacity once in first 'Start fade' action if initially inactive
- this.fadeInTime = this.properties[1];
- this.waitTime = this.properties[2];
- this.fadeOutTime = this.properties[3];
- this.destroy = this.properties[4]; // 0 = no, 1 = after fade out
- this.stage = this.activeAtStart ? 0 : 3; // 0 = fade in, 1 = wait, 2 = fade out, 3 = done
- if (this.recycled)
- this.stageTime.reset();
- else
- this.stageTime = new cr.KahanAdder();
- this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
- if (this.activeAtStart)
- {
- if (this.fadeInTime === 0)
- {
- this.stage = 1;
- if (this.waitTime === 0)
- this.stage = 2;
- }
- else
- {
- this.inst.opacity = 0;
- this.runtime.redraw = true;
- }
- }
- };
- behinstProto.saveToJSON = function ()
- {
- return {
- "fit": this.fadeInTime,
- "wt": this.waitTime,
- "fot": this.fadeOutTime,
- "s": this.stage,
- "st": this.stageTime.sum,
- "mo": this.maxOpacity,
- };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.fadeInTime = o["fit"];
- this.waitTime = o["wt"];
- this.fadeOutTime = o["fot"];
- this.stage = o["s"];
- this.stageTime.reset();
- this.stageTime.sum = o["st"];
- this.maxOpacity = o["mo"];
- };
- behinstProto.tick = function ()
- {
- this.stageTime.add(this.runtime.getDt(this.inst));
- if (this.stage === 0)
- {
- this.inst.opacity = (this.stageTime.sum / this.fadeInTime) * this.maxOpacity;
- this.runtime.redraw = true;
- if (this.inst.opacity >= this.maxOpacity)
- {
- this.inst.opacity = this.maxOpacity;
- this.stage = 1; // wait stage
- this.stageTime.reset();
- this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeInEnd, this.inst);
- }
- }
- if (this.stage === 1)
- {
- if (this.stageTime.sum >= this.waitTime)
- {
- this.stage = 2; // fade out stage
- this.stageTime.reset();
- this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnWaitEnd, this.inst);
- }
- }
- if (this.stage === 2)
- {
- if (this.fadeOutTime !== 0)
- {
- this.inst.opacity = this.maxOpacity - ((this.stageTime.sum / this.fadeOutTime) * this.maxOpacity);
- this.runtime.redraw = true;
- if (this.inst.opacity < 0)
- {
- this.inst.opacity = 0;
- this.stage = 3; // done
- this.stageTime.reset();
- this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeOutEnd, this.inst);
- if (this.destroy === 1)
- this.runtime.DestroyInstance(this.inst);
- }
- }
- }
- };
- behinstProto.doStart = function ()
- {
- this.stage = 0;
- this.stageTime.reset();
- if (this.fadeInTime === 0)
- {
- this.stage = 1;
- if (this.waitTime === 0)
- this.stage = 2;
- }
- else
- {
- this.inst.opacity = 0;
- this.runtime.redraw = true;
- }
- };
- function Cnds() {};
- Cnds.prototype.OnFadeOutEnd = function ()
- {
- return true;
- };
- Cnds.prototype.OnFadeInEnd = function ()
- {
- return true;
- };
- Cnds.prototype.OnWaitEnd = function ()
- {
- return true;
- };
- behaviorProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.StartFade = function ()
- {
- if (!this.activeAtStart && !this.setMaxOpacity)
- {
- this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
- this.setMaxOpacity = true;
- }
- if (this.stage === 3)
- this.doStart();
- };
- Acts.prototype.RestartFade = function ()
- {
- this.doStart();
- };
- Acts.prototype.SetFadeInTime = function (t)
- {
- if (t < 0)
- t = 0;
- this.fadeInTime = t;
- };
- Acts.prototype.SetWaitTime = function (t)
- {
- if (t < 0)
- t = 0;
- this.waitTime = t;
- };
- Acts.prototype.SetFadeOutTime = function (t)
- {
- if (t < 0)
- t = 0;
- this.fadeOutTime = t;
- };
- behaviorProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.FadeInTime = function (ret)
- {
- ret.set_float(this.fadeInTime);
- };
- Exps.prototype.WaitTime = function (ret)
- {
- ret.set_float(this.waitTime);
- };
- Exps.prototype.FadeOutTime = function (ret)
- {
- ret.set_float(this.fadeOutTime);
- };
- behaviorProto.exps = new Exps();
-}());
-;
-;
-cr.behaviors.Pin = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.Pin.prototype;
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- };
- var behinstProto = behaviorProto.Instance.prototype;
- behinstProto.onCreate = function()
- {
- this.pinObject = null;
- this.pinObjectUid = -1; // for loading
- this.pinAngle = 0;
- this.pinDist = 0;
- this.myStartAngle = 0;
- this.theirStartAngle = 0;
- this.lastKnownAngle = 0;
- this.mode = 0; // 0 = position & angle; 1 = position; 2 = angle; 3 = rope; 4 = bar
- var self = this;
- if (!this.recycled)
- {
- this.myDestroyCallback = (function(inst) {
- self.onInstanceDestroyed(inst);
- });
- }
- this.runtime.addDestroyCallback(this.myDestroyCallback);
- };
- behinstProto.saveToJSON = function ()
- {
- return {
- "uid": this.pinObject ? this.pinObject.uid : -1,
- "pa": this.pinAngle,
- "pd": this.pinDist,
- "msa": this.myStartAngle,
- "tsa": this.theirStartAngle,
- "lka": this.lastKnownAngle,
- "m": this.mode
- };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.pinObjectUid = o["uid"]; // wait until afterLoad to look up
- this.pinAngle = o["pa"];
- this.pinDist = o["pd"];
- this.myStartAngle = o["msa"];
- this.theirStartAngle = o["tsa"];
- this.lastKnownAngle = o["lka"];
- this.mode = o["m"];
- };
- behinstProto.afterLoad = function ()
- {
- if (this.pinObjectUid === -1)
- this.pinObject = null;
- else
- {
- this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid);
-;
- }
- this.pinObjectUid = -1;
- };
- behinstProto.onInstanceDestroyed = function (inst)
- {
- if (this.pinObject == inst)
- this.pinObject = null;
- };
- behinstProto.onDestroy = function()
- {
- this.pinObject = null;
- this.runtime.removeDestroyCallback(this.myDestroyCallback);
- };
- behinstProto.tick = function ()
- {
- };
- behinstProto.tick2 = function ()
- {
- if (!this.pinObject)
- return;
- if (this.lastKnownAngle !== this.inst.angle)
- this.myStartAngle = cr.clamp_angle(this.myStartAngle + (this.inst.angle - this.lastKnownAngle));
- var newx = this.inst.x;
- var newy = this.inst.y;
- if (this.mode === 3 || this.mode === 4) // rope mode or bar mode
- {
- var dist = cr.distanceTo(this.inst.x, this.inst.y, this.pinObject.x, this.pinObject.y);
- if ((dist > this.pinDist) || (this.mode === 4 && dist < this.pinDist))
- {
- var a = cr.angleTo(this.pinObject.x, this.pinObject.y, this.inst.x, this.inst.y);
- newx = this.pinObject.x + Math.cos(a) * this.pinDist;
- newy = this.pinObject.y + Math.sin(a) * this.pinDist;
- }
- }
- else
- {
- newx = this.pinObject.x + Math.cos(this.pinObject.angle + this.pinAngle) * this.pinDist;
- newy = this.pinObject.y + Math.sin(this.pinObject.angle + this.pinAngle) * this.pinDist;
- }
- var newangle = cr.clamp_angle(this.myStartAngle + (this.pinObject.angle - this.theirStartAngle));
- this.lastKnownAngle = newangle;
- if ((this.mode === 0 || this.mode === 1 || this.mode === 3 || this.mode === 4)
- && (this.inst.x !== newx || this.inst.y !== newy))
- {
- this.inst.x = newx;
- this.inst.y = newy;
- this.inst.set_bbox_changed();
- }
- if ((this.mode === 0 || this.mode === 2) && (this.inst.angle !== newangle))
- {
- this.inst.angle = newangle;
- this.inst.set_bbox_changed();
- }
- };
- function Cnds() {};
- Cnds.prototype.IsPinned = function ()
- {
- return !!this.pinObject;
- };
- behaviorProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.Pin = function (obj, mode_)
- {
- if (!obj)
- return;
- var otherinst = obj.getFirstPicked(this.inst);
- if (!otherinst)
- return;
- this.pinObject = otherinst;
- this.pinAngle = cr.angleTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y) - otherinst.angle;
- this.pinDist = cr.distanceTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y);
- this.myStartAngle = this.inst.angle;
- this.lastKnownAngle = this.inst.angle;
- this.theirStartAngle = otherinst.angle;
- this.mode = mode_;
- };
- Acts.prototype.Unpin = function ()
- {
- this.pinObject = null;
- };
- behaviorProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.PinnedUID = function (ret)
- {
- ret.set_int(this.pinObject ? this.pinObject.uid : -1);
- };
- behaviorProto.exps = new Exps();
-}());
-;
-;
-cr.behaviors.Rex_MoveTo = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.Rex_MoveTo.prototype;
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- };
- var behinstProto = behaviorProto.Instance.prototype;
- behinstProto.onCreate = function()
- {
- this.enabled = (this.properties[0] == 1);
- if (!this.recycled)
- {
- this.move = {"max":0,
- "acc":0,
- "dec":0};
- }
- this.move["max"] = this.properties[1];
- this.move["acc"] = this.properties[2];
- this.move["dec"] = this.properties[3];
- if (!this.recycled)
- {
- this.target = {"x":0 , "y":0, "a":0};
- }
- this.is_moving = false;
- this.current_speed = 0;
- this.remain_distance = 0;
- this.is_hit_target = false;
- if (!this.recycled)
- {
- this._pre_pos = {"x":0,"y":0};
- }
- this._pre_pos["x"] = 0;
- this._pre_pos["y"] = 0;
- if (!this.recycled)
- {
- this._moving_angle_info = {"x":0,"y":0,"a":(-1)};
- }
- this._moving_angle_info["x"] = 0;
- this._moving_angle_info["y"] = 0;
- this._moving_angle_info["a"] = -1;
- this._last_tick = null;
- this.is_my_call = false;
- };
- behinstProto.tick = function ()
- {
- if (this.is_hit_target)
- {
- if ((this.inst.x == this.target["x"]) && (this.inst.y == this.target["y"]))
- {
- this.is_my_call = true;
- this.runtime.trigger(cr.behaviors.Rex_MoveTo.prototype.cnds.OnHitTarget, this.inst);
- this.is_my_call = false;
- }
- this.is_hit_target = false;
- }
- if ( (!this.enabled) || (!this.is_moving) )
- {
- return;
- }
- var dt = this.runtime.getDt(this.inst);
- if (dt==0) // can not move if dt == 0
- return;
- if ((this._pre_pos["x"] != this.inst.x) || (this._pre_pos["y"] != this.inst.y))
- this._reset_current_pos(); // reset this.remain_distance
- var is_slow_down = false;
- if (this.move["dec"] != 0)
- {
- var _speed = this.current_speed;
- var _distance = (_speed*_speed)/(2*this.move["dec"]); // (v*v)/(2*a)
- is_slow_down = (_distance >= this.remain_distance);
- }
- var acc = (is_slow_down)? (-this.move["dec"]):this.move["acc"];
- if (acc != 0)
- {
- this.SetCurrentSpeed( this.current_speed + (acc * dt) );
- }
- var distance = this.current_speed * dt;
- this.remain_distance -= distance;
- if ( (this.remain_distance <= 0) || (this.current_speed <= 0) )
- {
- this.is_moving = false;
- this.inst.x = this.target["x"];
- this.inst.y = this.target["y"];
- this.SetCurrentSpeed(0);
- this.moving_angle_get();
- this.is_hit_target = true;
- }
- else
- {
- var angle = this.target["a"];
- this.inst.x += (distance * Math.cos(angle));
- this.inst.y += (distance * Math.sin(angle));
- }
- this.inst.set_bbox_changed();
- this._pre_pos["x"] = this.inst.x;
- this._pre_pos["y"] = this.inst.y;
- };
- behinstProto.tick2 = function ()
- {
- this._moving_angle_info["x"] = this.inst.x;
- this._moving_angle_info["y"] = this.inst.y;
- };
- behinstProto.SetCurrentSpeed = function(speed)
- {
- if (speed != null)
- {
- this.current_speed = (speed > this.move["max"])?
- this.move["max"]: speed;
- }
- else if (this.move["acc"]==0)
- {
- this.current_speed = this.move["max"];
- }
- };
- behinstProto._reset_current_pos = function ()
- {
- var dx = this.target["x"] - this.inst.x;
- var dy = this.target["y"] - this.inst.y;
- this.target["a"] = Math.atan2(dy, dx);
- this.remain_distance = Math.sqrt( (dx*dx) + (dy*dy) );
- this._pre_pos["x"] = this.inst.x;
- this._pre_pos["y"] = this.inst.y;
- };
- behinstProto.SetTargetPos = function (_x, _y)
- {
- this.is_moving = true;
- this.target["x"] = _x;
- this.target["y"] = _y;
- this._reset_current_pos();
- this.SetCurrentSpeed(null);
- this._moving_angle_info["x"] = this.inst.x;
- this._moving_angle_info["y"] = this.inst.y;
- };
- behinstProto.KENSetTargetPos = function (_x, _y)
- {
- this.target["x"] = _x;
- this.target["y"] = _y;
- this._reset_current_pos();
- this.is_moving = false;
- this.inst.x = this.target["x"];
- this.inst.y = this.target["y"];
- this.SetCurrentSpeed(0);
- this.moving_angle_get();
- this.is_moving = true;
- };
- behinstProto.is_tick_changed = function ()
- {
- var cur_tick = this.runtime.tickcount;
- var tick_changed = (this._last_tick != cur_tick);
- this._last_tick = cur_tick;
- return tick_changed;
- };
- behinstProto.moving_angle_get = function (ret)
- {
- if (this.is_tick_changed())
- {
- var dx = this.inst.x - this._moving_angle_info["x"];
- var dy = this.inst.y - this._moving_angle_info["y"];
- if ((dx!=0) || (dy!=0))
- this._moving_angle_info["a"] = cr.to_clamped_degrees(Math.atan2(dy,dx));
- }
- return this._moving_angle_info["a"];
- };
- behinstProto.saveToJSON = function ()
- {
- return { "en": this.enabled,
- "v": this.move,
- "t": this.target,
- "is_m": this.is_moving,
- "c_spd" : this.current_speed,
- "rd" : this.remain_distance,
- "is_ht" : this.is_hit_target,
- "pp": this._pre_pos,
- "ma": this._moving_angle_info,
- "lt": this._last_tick,
- };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.enabled = o["en"];
- this.move = o["v"];
- this.target = o["t"];
- this.is_moving = o["is_m"];
- this.current_speed = o["c_spd"];
- this.remain_distance = o["rd"];
- this.is_hit_target = o["is_ht"];
- this._pre_pos = o["pp"];
- this._moving_angle_info = o["ma"];
- this._last_tick = o["lt"];
- };
- function Cnds() {};
- behaviorProto.cnds = new Cnds();
- Cnds.prototype.OnHitTarget = function ()
- {
- return (this.is_my_call);
- };
- Cnds.prototype.CompareSpeed = function (cmp, s)
- {
- return cr.do_cmp(this.current_speed, cmp, s);
- };
- Cnds.prototype.OnMoving = function () // deprecated
- {
- return false;
- };
- Cnds.prototype.IsMoving = function ()
- {
- return (this.enabled && this.is_moving);
- };
- Cnds.prototype.CompareMovingAngle = function (cmp, s)
- {
- var angle = this.moving_angle_get();
- if (angle != (-1))
- return cr.do_cmp(this.moving_angle_get(), cmp, s);
- else
- return false;
- };
- function Acts() {};
- behaviorProto.acts = new Acts();
- Acts.prototype.SetEnabled = function (en)
- {
- this.enabled = (en === 1);
- };
- Acts.prototype.SetMaxSpeed = function (s)
- {
- this.move["max"] = s;
- this.SetCurrentSpeed(null);
- };
- Acts.prototype.SetAcceleration = function (a)
- {
- this.move["acc"] = a;
- this.SetCurrentSpeed(null);
- };
- Acts.prototype.SetDeceleration = function (a)
- {
- this.move["dec"] = a;
- };
- Acts.prototype.SetTargetPos = function (_x, _y)
- {
- this.SetTargetPos(_x, _y)
- };
- Acts.prototype.KENSetTargetPos = function (_x, _y)
- {
- this.KENSetTargetPos(_x, _y)
- };
- Acts.prototype.SetCurrentSpeed = function (s)
- {
- this.SetCurrentSpeed(s);
- };
- Acts.prototype.SetTargetPosOnObject = function (objtype)
- {
- if (!objtype)
- return;
- var inst = objtype.getFirstPicked();
- if (inst != null)
- this.SetTargetPos(inst.x, inst.y);
- };
- Acts.prototype.SetTargetPosByDeltaXY = function (dx, dy)
- {
- this.SetTargetPos(this.inst.x + dx, this.inst.y + dy);
- };
- Acts.prototype.SetTargetPosByDistanceAngle = function (distance, angle)
- {
- var a = cr.to_clamped_radians(angle);
- var dx = distance*Math.cos(a);
- var dy = distance*Math.sin(a);
- this.SetTargetPos(this.inst.x + dx, this.inst.y + dy);
- };
- Acts.prototype.Stop = function ()
- {
- this.is_moving = false;
- };
- function Exps() {};
- behaviorProto.exps = new Exps();
- Exps.prototype.Activated = function (ret)
- {
- ret.set_int((this.enabled)? 1:0);
- };
- Exps.prototype.Speed = function (ret)
- {
- ret.set_float(this.current_speed);
- };
- Exps.prototype.MaxSpeed = function (ret)
- {
- ret.set_float(this.move["max"]);
- };
- Exps.prototype.Acc = function (ret)
- {
- ret.set_float(this.move["acc"]);
- };
- Exps.prototype.Dec = function (ret)
- {
- ret.set_float(this.move["dec"]);
- };
- Exps.prototype.TargetX = function (ret)
- {
- ret.set_float(this.target["x"]);
- };
- Exps.prototype.TargetY = function (ret)
- {
- ret.set_float(this.target["y"]);
- };
- Exps.prototype.MovingAngle = function (ret)
- {
- ret.set_float(this.moving_angle_get());
- };
-}());
-;
-;
-cr.behaviors.Sin = function(runtime)
-{
- this.runtime = runtime;
-};
-(function ()
-{
- var behaviorProto = cr.behaviors.Sin.prototype;
- behaviorProto.Type = function(behavior, objtype)
- {
- this.behavior = behavior;
- this.objtype = objtype;
- this.runtime = behavior.runtime;
- };
- var behtypeProto = behaviorProto.Type.prototype;
- behtypeProto.onCreate = function()
- {
- };
- behaviorProto.Instance = function(type, inst)
- {
- this.type = type;
- this.behavior = type.behavior;
- this.inst = inst; // associated object instance to modify
- this.runtime = type.runtime;
- this.i = 0; // period offset (radians)
- };
- var behinstProto = behaviorProto.Instance.prototype;
- var _2pi = 2 * Math.PI;
- var _pi_2 = Math.PI / 2;
- var _3pi_2 = (3 * Math.PI) / 2;
- behinstProto.onCreate = function()
- {
- this.active = (this.properties[0] === 1);
- this.movement = this.properties[1]; // 0=Horizontal|1=Vertical|2=Size|3=Width|4=Height|5=Angle|6=Opacity|7=Value only
- this.wave = this.properties[2]; // 0=Sine|1=Triangle|2=Sawtooth|3=Reverse sawtooth|4=Square
- this.period = this.properties[3];
- this.period += Math.random() * this.properties[4]; // period random
- if (this.period === 0)
- this.i = 0;
- else
- {
- this.i = (this.properties[5] / this.period) * _2pi; // period offset
- this.i += ((Math.random() * this.properties[6]) / this.period) * _2pi; // period offset random
- }
- this.mag = this.properties[7]; // magnitude
- this.mag += Math.random() * this.properties[8]; // magnitude random
- this.initialValue = 0;
- this.initialValue2 = 0;
- this.ratio = 0;
- if (this.movement === 5) // angle
- this.mag = cr.to_radians(this.mag);
- this.init();
- };
- behinstProto.saveToJSON = function ()
- {
- return {
- "i": this.i,
- "a": this.active,
- "mv": this.movement,
- "w": this.wave,
- "p": this.period,
- "mag": this.mag,
- "iv": this.initialValue,
- "iv2": this.initialValue2,
- "r": this.ratio,
- "lkv": this.lastKnownValue,
- "lkv2": this.lastKnownValue2
- };
- };
- behinstProto.loadFromJSON = function (o)
- {
- this.i = o["i"];
- this.active = o["a"];
- this.movement = o["mv"];
- this.wave = o["w"];
- this.period = o["p"];
- this.mag = o["mag"];
- this.initialValue = o["iv"];
- this.initialValue2 = o["iv2"] || 0;
- this.ratio = o["r"];
- this.lastKnownValue = o["lkv"];
- this.lastKnownValue2 = o["lkv2"] || 0;
- };
- behinstProto.init = function ()
- {
- switch (this.movement) {
- case 0: // horizontal
- this.initialValue = this.inst.x;
- break;
- case 1: // vertical
- this.initialValue = this.inst.y;
- break;
- case 2: // size
- this.initialValue = this.inst.width;
- this.ratio = this.inst.height / this.inst.width;
- break;
- case 3: // width
- this.initialValue = this.inst.width;
- break;
- case 4: // height
- this.initialValue = this.inst.height;
- break;
- case 5: // angle
- this.initialValue = this.inst.angle;
- break;
- case 6: // opacity
- this.initialValue = this.inst.opacity;
- break;
- case 7:
- this.initialValue = 0;
- break;
- case 8: // forwards/backwards
- this.initialValue = this.inst.x;
- this.initialValue2 = this.inst.y;
- break;
- default:
-;
- }
- this.lastKnownValue = this.initialValue;
- this.lastKnownValue2 = this.initialValue2;
- };
- behinstProto.waveFunc = function (x)
- {
- x = x % _2pi;
- switch (this.wave) {
- case 0: // sine
- return Math.sin(x);
- case 1: // triangle
- if (x <= _pi_2)
- return x / _pi_2;
- else if (x <= _3pi_2)
- return 1 - (2 * (x - _pi_2) / Math.PI);
- else
- return (x - _3pi_2) / _pi_2 - 1;
- case 2: // sawtooth
- return 2 * x / _2pi - 1;
- case 3: // reverse sawtooth
- return -2 * x / _2pi + 1;
- case 4: // square
- return x < Math.PI ? -1 : 1;
- };
- return 0;
- };
- behinstProto.tick = function ()
- {
- var dt = this.runtime.getDt(this.inst);
- if (!this.active || dt === 0)
- return;
- if (this.period === 0)
- this.i = 0;
- else
- {
- this.i += (dt / this.period) * _2pi;
- this.i = this.i % _2pi;
- }
- this.updateFromPhase();
- };
- behinstProto.updateFromPhase = function ()
- {
- switch (this.movement) {
- case 0: // horizontal
- if (this.inst.x !== this.lastKnownValue)
- this.initialValue += this.inst.x - this.lastKnownValue;
- this.inst.x = this.initialValue + this.waveFunc(this.i) * this.mag;
- this.lastKnownValue = this.inst.x;
- break;
- case 1: // vertical
- if (this.inst.y !== this.lastKnownValue)
- this.initialValue += this.inst.y - this.lastKnownValue;
- this.inst.y = this.initialValue + this.waveFunc(this.i) * this.mag;
- this.lastKnownValue = this.inst.y;
- break;
- case 2: // size
- this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
- this.inst.height = this.inst.width * this.ratio;
- break;
- case 3: // width
- this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
- break;
- case 4: // height
- this.inst.height = this.initialValue + this.waveFunc(this.i) * this.mag;
- break;
- case 5: // angle
- if (this.inst.angle !== this.lastKnownValue)
- this.initialValue = cr.clamp_angle(this.initialValue + (this.inst.angle - this.lastKnownValue));
- this.inst.angle = cr.clamp_angle(this.initialValue + this.waveFunc(this.i) * this.mag);
- this.lastKnownValue = this.inst.angle;
- break;
- case 6: // opacity
- this.inst.opacity = this.initialValue + (this.waveFunc(this.i) * this.mag) / 100;
- if (this.inst.opacity < 0)
- this.inst.opacity = 0;
- else if (this.inst.opacity > 1)
- this.inst.opacity = 1;
- break;
- case 8: // forwards/backwards
- if (this.inst.x !== this.lastKnownValue)
- this.initialValue += this.inst.x - this.lastKnownValue;
- if (this.inst.y !== this.lastKnownValue2)
- this.initialValue2 += this.inst.y - this.lastKnownValue2;
- this.inst.x = this.initialValue + Math.cos(this.inst.angle) * this.waveFunc(this.i) * this.mag;
- this.inst.y = this.initialValue2 + Math.sin(this.inst.angle) * this.waveFunc(this.i) * this.mag;
- this.lastKnownValue = this.inst.x;
- this.lastKnownValue2 = this.inst.y;
- break;
- }
- this.inst.set_bbox_changed();
- };
- behinstProto.onSpriteFrameChanged = function (prev_frame, next_frame)
- {
- switch (this.movement) {
- case 2: // size
- this.initialValue *= (next_frame.width / prev_frame.width);
- this.ratio = next_frame.height / next_frame.width;
- break;
- case 3: // width
- this.initialValue *= (next_frame.width / prev_frame.width);
- break;
- case 4: // height
- this.initialValue *= (next_frame.height / prev_frame.height);
- break;
- }
- };
- function Cnds() {};
- Cnds.prototype.IsActive = function ()
- {
- return this.active;
- };
- Cnds.prototype.CompareMovement = function (m)
- {
- return this.movement === m;
- };
- Cnds.prototype.ComparePeriod = function (cmp, v)
- {
- return cr.do_cmp(this.period, cmp, v);
- };
- Cnds.prototype.CompareMagnitude = function (cmp, v)
- {
- if (this.movement === 5)
- return cr.do_cmp(this.mag, cmp, cr.to_radians(v));
- else
- return cr.do_cmp(this.mag, cmp, v);
- };
- Cnds.prototype.CompareWave = function (w)
- {
- return this.wave === w;
- };
- behaviorProto.cnds = new Cnds();
- function Acts() {};
- Acts.prototype.SetActive = function (a)
- {
- this.active = (a === 1);
- };
- Acts.prototype.SetPeriod = function (x)
- {
- this.period = x;
- };
- Acts.prototype.SetMagnitude = function (x)
- {
- this.mag = x;
- if (this.movement === 5) // angle
- this.mag = cr.to_radians(this.mag);
- };
- Acts.prototype.SetMovement = function (m)
- {
- if (this.movement === 5 && m !== 5)
- this.mag = cr.to_degrees(this.mag);
- this.movement = m;
- this.init();
- };
- Acts.prototype.SetWave = function (w)
- {
- this.wave = w;
- };
- Acts.prototype.SetPhase = function (x)
- {
- this.i = (x * _2pi) % _2pi;
- this.updateFromPhase();
- };
- Acts.prototype.UpdateInitialState = function ()
- {
- this.init();
- };
- behaviorProto.acts = new Acts();
- function Exps() {};
- Exps.prototype.CyclePosition = function (ret)
- {
- ret.set_float(this.i / _2pi);
- };
- Exps.prototype.Period = function (ret)
- {
- ret.set_float(this.period);
- };
- Exps.prototype.Magnitude = function (ret)
- {
- if (this.movement === 5) // angle
- ret.set_float(cr.to_degrees(this.mag));
- else
- ret.set_float(this.mag);
- };
- Exps.prototype.Value = function (ret)
- {
- ret.set_float(this.waveFunc(this.i) * this.mag);
- };
- behaviorProto.exps = new Exps();
-}());
-cr.getObjectRefTable = function () { return [
- cr.plugins_.Audio,
- cr.plugins_.Browser,
- cr.plugins_.Function,
- cr.plugins_.Sprite,
- cr.plugins_.SenaPlugin,
- cr.plugins_.SpriteFontPlus,
- cr.plugins_.Touch,
- cr.behaviors.Fade,
- cr.behaviors.DragnDrop,
- cr.behaviors.Rex_MoveTo,
- cr.behaviors.Sin,
- cr.behaviors.Pin,
- cr.system_object.prototype.cnds.OnLayoutStart,
- cr.plugins_.SenaPlugin.prototype.acts.Load,
- cr.system_object.prototype.acts.SetLayerVisible,
- cr.plugins_.SenaPlugin.prototype.cnds.OnLoad,
- cr.plugins_.Browser.prototype.acts.ConsoleLog,
- cr.plugins_.SenaPlugin.prototype.exps.getGuide,
- cr.plugins_.SenaPlugin.prototype.acts.Start,
- cr.plugins_.SenaPlugin.prototype.cnds.OnStart,
- cr.plugins_.SenaPlugin.prototype.exps.getQuestionType,
- cr.plugins_.SenaPlugin.prototype.exps.getQuestionValue,
- cr.plugins_.SenaPlugin.prototype.exps.getRequestType,
- cr.plugins_.SenaPlugin.prototype.exps.getRequestValue,
- cr.plugins_.SenaPlugin.prototype.exps.getOptionsCount,
- cr.plugins_.SenaPlugin.prototype.exps.getHintCount,
- cr.plugins_.Sprite.prototype.acts.Destroy,
- cr.system_object.prototype.acts.SetVar,
- cr.system_object.prototype.exps["int"],
- cr.plugins_.SpriteFontPlus.prototype.acts.SetText,
- cr.behaviors.Pin.prototype.acts.Pin,
- cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
- cr.plugins_.Sprite.prototype.exps.X,
- cr.plugins_.Sprite.prototype.exps.Y,
- cr.plugins_.Sprite.prototype.acts.SetPos,
- cr.plugins_.SenaPlugin.prototype.acts.CalcObjectPositions,
- cr.plugins_.Sprite.prototype.exps.Width,
- cr.system_object.prototype.cnds.Repeat,
- cr.system_object.prototype.exps.loopindex,
- cr.plugins_.SenaPlugin.prototype.exps.getHintType,
- cr.plugins_.SenaPlugin.prototype.exps.getHintValue,
- cr.system_object.prototype.acts.CreateObject,
- cr.plugins_.SenaPlugin.prototype.exps.getPosXbyIndex,
- cr.plugins_.SenaPlugin.prototype.exps.getPosYbyIndex,
- cr.system_object.prototype.cnds.Compare,
- cr.plugins_.Sprite.prototype.acts.SetBoolInstanceVar,
- cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
- cr.system_object.prototype.cnds.Else,
- cr.plugins_.Sprite.prototype.acts.SetY,
- cr.plugins_.SenaPlugin.prototype.exps.getOptionsType,
- cr.plugins_.SenaPlugin.prototype.exps.getOptionsValue,
- cr.plugins_.Touch.prototype.cnds.OnTouchObject,
- cr.plugins_.Sprite.prototype.cnds.IsVisible,
- cr.system_object.prototype.cnds.CompareVar,
- cr.plugins_.Audio.prototype.acts.Play,
- cr.plugins_.SenaPlugin.prototype.acts.PauseGame,
- cr.behaviors.DragnDrop.prototype.acts.SetEnabled,
- cr.plugins_.Function.prototype.acts.CallFunction,
- cr.system_object.prototype.acts.Wait,
- cr.plugins_.SenaPlugin.prototype.cnds.OnCorrect,
- cr.plugins_.SenaPlugin.prototype.cnds.OnWrong,
- cr.plugins_.SenaPlugin.prototype.acts.ResumeGame,
- cr.plugins_.SenaPlugin.prototype.cnds.OnPause,
- cr.plugins_.SenaPlugin.prototype.cnds.OnResume,
- cr.system_object.prototype.cnds.EveryTick,
- cr.plugins_.SenaPlugin.prototype.exps.getTimeLimit,
- cr.system_object.prototype.exps.max,
- cr.plugins_.SenaPlugin.prototype.exps.getElapsedTime,
- cr.system_object.prototype.cnds.TriggerOnce,
- cr.plugins_.SpriteFontPlus.prototype.acts.Destroy,
- cr.behaviors.Fade.prototype.acts.StartFade,
- cr.plugins_.SenaPlugin.prototype.acts.Finish,
- cr.plugins_.Function.prototype.cnds.OnFunction,
- cr.system_object.prototype.cnds.For,
- cr.system_object.prototype.cnds.PickByComparison,
- cr.system_object.prototype.exps.left,
- cr.system_object.prototype.exps.len,
- cr.plugins_.Sprite.prototype.cnds.CompareY,
- cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPos,
- cr.behaviors.Rex_MoveTo.prototype.acts.SetTargetPosOnObject,
- cr.plugins_.Sprite.prototype.cnds.CompareFrame,
- cr.plugins_.Audio.prototype.acts.SetSilent,
- cr.system_object.prototype.cnds.LayerVisible,
- cr.behaviors.DragnDrop.prototype.cnds.OnDragStart,
- cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
- cr.plugins_.Sprite.prototype.cnds.IsOverlapping,
- cr.plugins_.Sprite.prototype.acts.MoveToTop,
- cr.plugins_.SpriteFontPlus.prototype.acts.MoveToTop,
- cr.behaviors.DragnDrop.prototype.cnds.OnDrop,
- cr.plugins_.Sprite.prototype.cnds.IsBoolInstanceVarSet,
- cr.plugins_.Sprite.prototype.cnds.PickDistance,
- cr.behaviors.Rex_MoveTo.prototype.acts.SetMaxSpeed,
- cr.system_object.prototype.acts.AddVar,
- cr.behaviors.DragnDrop.prototype.cnds.IsDragging,
- cr.plugins_.Touch.prototype.exps.X,
- cr.plugins_.Touch.prototype.exps.Y,
- cr.plugins_.Sprite.prototype.acts.SetVisible
-];};
-
diff --git a/New-project/data.js b/New-project/data.js
deleted file mode 100644
index f5103a4..0000000
--- a/New-project/data.js
+++ /dev/null
@@ -1 +0,0 @@
-{"project": [null,null,[[0,true,false,false,false,false,false,false,false,false],[1,true,false,false,false,false,false,false,false,false],[2,true,false,false,false,false,false,false,false,false],[3,false,true,true,true,true,true,true,true,false],[4,true,false,false,false,false,false,false,false,false],[5,false,true,true,true,true,true,true,true,true],[6,true,false,false,false,false,false,false,false,false]],[["t0",4,false,[],0,0,null,null,[],false,false,394152958375253,[],null,["G2800S1T30"]],["t1",1,false,[],0,0,null,null,[],false,false,181015701933739,[],null,[]],["t2",3,false,[],0,0,null,[["Default",5,false,1,0,false,266653407798345,[["images/btn_check-sheet0.png",17703,0,0,165,75,1,0.5030303001403809,0.5066666603088379,[],[],0]]]],[],false,false,870372553390403,[],null],["t3",3,false,[],0,0,null,[["Default",5,false,1,0,false,644390976254011,[["images/wrong-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,726240664871372,[],null],["t4",6,false,[],0,0,null,null,[],false,false,288430412484243,[],null,[1]],["t5",3,false,[],0,0,null,[["Default",5,false,1,0,false,974942116247628,[["images/pause-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,829278278494442,[],null],["t6",3,false,[],0,0,null,[["Default",5,false,1,0,false,830476950235748,[["images/pause-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[],false,false,250461366236378,[],null],["t7",3,false,[839027338172447,370467464601183,403859397610033],1,0,null,[["Default",0,false,1,0,false,201845729772152,[["images/slot-sheet0.png",36041,1,1,200,75,1,0.5,0.5066666603088379,[],[],0],["images/slot-sheet0.png",36041,1,78,200,75,1,0.5,0.4933333396911621,[],[],0],["images/slot-sheet0.png",36041,1,155,200,75,1,0.4350000023841858,0.5199999809265137,[],[],0]]]],[["Fade",7,588103285968005]],false,false,530929310100717,[],null],["t8",3,false,[401281652261798,308058330719086,937883104346632,243525000976275,435711195864159],3,0,null,[["Default",5,false,1,0,false,344548683716056,[["images/slot-sheet0.png",36041,1,78,200,75,1,0.5,0.4933333396911621,[],[],0]]]],[["DragDrop",8,551257499299552],["Fade",7,430149822241515],["MoveTo",9,551694077436381]],false,false,515230787966511,[],null],["t9",2,false,[],0,0,null,null,[],false,false,825652157577718,[],null,[]],["t10",5,false,[],0,0,["images/txt_texttimer.png",94512,0],null,[],false,false,428453985749595,[],null],["t11",5,false,[],0,0,["images/txt_worditem.png",94801,0],null,[],false,false,125516006976486,[],null],["t12",5,false,[],0,0,["images/txt_texttimer.png",94512,0],null,[],false,false,680183373657896,[],null],["t13",3,false,[],0,0,null,[["Default",5,false,1,0,false,943124209669759,[["images/5sosarahtakesoff-sheet0.png",1099565,0,0,1400,900,1,0.5,0.5,[],[],1]]]],[],false,false,663734962307467,[],null],["t14",3,false,[],0,0,null,[["Default",5,false,1,0,false,174194635978617,[["images/senaaikhoi-sheet0.png",230528,0,0,1145,446,1,0.4995633065700531,0.4977578520774841,[],[],0]]]],[],false,false,577948289650662,[],null],["t15",3,false,[],0,0,null,[["Default",0,false,1,0,false,329974099612225,[["images/checker_wrong_correct-sheet0.png",10219,0,0,140,140,1,0.5,0.5,[],[-0.3642860054969788,-0.3642860054969788,0,-0.4357143044471741,0.3642860054969788,-0.3642860054969788,0.3999999761581421,0,0.3142859935760498,0.3142859935760498,0,0.442857027053833,-0.2928569912910461,0.2928569912910461,-0.3857139945030212,0],0],["images/checker_wrong_correct-sheet1.png",7978,0,0,140,140,1,0.5,0.5,[],[-0.357142984867096,-0.357142984867096,0,-0.4357143044471741,0.357142984867096,-0.357142984867096,0.3857139945030212,0,0.3642860054969788,0.3642860054969788,0,0.4142860174179077,-0.2857140004634857,0.2857139706611633,-0.3857139945030212,0],0]]]],[],false,false,246032193737445,[],null],["t16",0,false,[],0,0,null,null,[],false,false,396522085041537,[],null,[0,0,0,1,1,600,600,10000,1]],["t17",3,false,[],0,0,null,[["Default",5,false,1,0,false,857466576876240,[["images/btn_setting-sheet0.png",13202,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[-0.3656864762306213,-0.3547005355358124,-0.006272494792938232,-0.5028490424156189,0.355585515499115,-0.3547005355358124,0.485169529914856,-0.005494534969329834,0.3604755401611328,0.349002480506897,-0.006272494792938232,0.4865684509277344,-0.3681314587593079,0.3463574647903442,-0.4977155327796936,-0.005494534969329834],0]]]],[],false,false,444899307061590,[],null],["t18",3,false,[],0,0,null,[["Default",5,false,1,0,false,922486781068681,[["images/panel-sheet0.png",105765,0,0,815,474,1,0.5141104459762573,0.4852320551872253,[],[-0.4453988373279572,0.4156119227409363,-0.5067484974861145,-5.960464477539063e-008,-0.433128833770752,-0.3945147395133972,-4.172325134277344e-007,-0.4704641699790955,0.4184045791625977,-0.3691980540752411,0.4797545671463013,-5.960464477539063e-008,0.4294475317001343,0.3881859183311462,-4.172325134277344e-007,0.5084389448165894],0]]]],[],false,false,150393696478915,[],null],["t19",5,false,[],0,0,["images/txt_question.png",192019,0],null,[],false,false,389192760965508,[],null],["t20",3,false,[637523801130517,567457434227301],1,0,null,[["Default",5,false,1,0,false,177577261579169,[["images/btn_pause-sheet0.png",11757,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[-0.365747481584549,-0.3577375411987305,-0.005050480365753174,-0.5028560161590576,0.3556455373764038,-0.3577375411987305,0.4899744987487793,-0.006813526153564453,0.3581334948539734,0.34938645362854,-0.005050480365753174,0.4892284870147705,-0.365747481584549,0.3467484712600708,-0.4975878000259399,-0.006813526153564453],0]]]],[["MoveTo",9,345261300394347]],false,false,680660539195378,[],null],["t21",3,false,[546775332106909,966775272495183],1,0,null,[["Default",0,false,1,0,false,632596314970396,[["images/btn_music-sheet0.png",13358,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[],0],["images/btn_music-sheet1.png",14207,0,0,99,91,1,0.5050504803657532,0.5054945349693298,[],[],0]]]],[["MoveTo",9,561713266057788]],false,false,470943728107764,[],null],["t22",3,false,[],0,0,null,[["Default",5,false,1,0,false,804798480075980,[["images/panel_pause-sheet0.png",168,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,103999013142366,[],null],["t23",3,false,[],1,0,null,[["Default",5,false,1,0,false,794524614026990,[["images/layer-sheet0.png",111520,0,0,400,376,1,0.5,0.5,[],[-0.362500011920929,-0.3537229895591736,0,-0.5,0.362500011920929,-0.3537229895591736,0.497499942779541,0,0.3650000095367432,0.3563830256462097,0,0.5,-0.3650000095367432,0.3563830256462097,-0.5,0],0]]]],[["Sine",10,152768910804631]],false,false,822735679292648,[],null],["t24",3,false,[],0,0,null,[["Default",5,false,1,0,false,185281331107930,[["images/newwordpng-sheet0.png",166389,0,0,500,341,1,0.5,0.5014662742614746,[],[-0.3939999938011169,-0.3460412621498108,0,-0.4398826658725739,0.1480000019073486,0.01466274261474609,0.2919999957084656,-0.00293228030204773,0.4660000205039978,0.4486806988716126,0,0.4721407294273377,-0.4620000123977661,0.4428157210350037,-0.2820000052452087,-0.00293228030204773],0]]]],[],false,false,139959116973831,[],null],["t25",5,true,[],1,0,null,null,[["Pin",11,693926857619114]],false,false,154178255437462,[],null],["t26",3,true,[],0,0,null,null,[],false,false,909098946188328,[],null]],[[25,19,12,10,11],[26,21,20,17,23]],[["Layout 1",1200,1200,false,"Event sheet 1",148229480160171,[["BG",0,977906834634586,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600,600,0,1946.035888671875,1251.023071289063,0,0,1,0.5,0.5,0,0,[]],13,13,[],[],[0,"Default",0,1]]],[]],["Main",1,715835324311419,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600.5625,863,0,185.6243591308594,84.37471008300781,0,0,1,0.5030303001403809,0.5066666603088379,0,0,[]],2,2,[],[],[0,"Default",0,1]],[[998,-788,0,250,250,0,0,1,0.5,0.5,0,0,[]],3,3,[],[],[0,"Default",0,1]],[[314,-701,0,58,49,0,0,1,0.5,0.5,0,0,[]],5,5,[],[],[0,"Default",0,1]],[[313,-632,0,58.32666778564453,58.32666778564453,0,0,1,0.5,0.5,0,0,[]],6,6,[],[],[0,"Default",0,1]],[[209,-866,0,200,75,0,0,1,0.5,0.5066666603088379,0,0,[]],7,7,[[0],[""],[0]],[[0,0,0,2,1]],[0,"Default",0,1]],[[-35,-863,0,200,75,0,0,1,0.5,0.4933333396911621,0,0,[]],8,8,[[""],[0],[0],[-1],[0]],[[0,1],[0,0,0,2,1],[1,1200,0,0]],[0,"Default",0,1]],[[668,-675,0,160.2111206054688,55.53988647460938,0,0,1,0.5,0.5,0,0,[]],11,11,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","Text",0.5,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[474,-928,0,160.2109985351563,55.54000091552734,0,0,1,0.5,0.5,0,0,[]],12,12,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","Text",0.5,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[1052,70,0,255.0779113769531,99.35787963867188,0,0,1,0.4995633065700531,0.4977578520774841,0,0,[]],14,14,[],[],[0,"Default",0,1]],[[1080,72,0,132,77,0,0,1,0.5,0.5,0,0,[]],10,10,[],[[]],[76,83,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@°+=*$£€<>%","TIME",0.7,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",\"],[22,\"`\"],[24,\")\"],[25,\"(\\\\/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1\"],[33,\"\\\"\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[39,\"s\"],[40,\"kx\"],[41,\"Jhnu\"],[42,\"v7?+=<>\"],[43,\"Faceyz0238\"],[44,\"L569_~$\"],[45,\"bdgopq\"],[46,\"P#\"],[47,\"EX\"],[48,\"S4€\"],[49,\"Y£\"],[50,\"BNR\"],[51,\"DHKTU\"],[52,\"VZ\"],[53,\"C\"],[54,\"A\"],[55,\"&\"],[56,\"GM\"],[57,\"O\"],[60,\"Q\"],[62,\"mw\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[109,-653,0,140,140,0,0,1,0.5,0.5,0,0,[]],15,15,[],[],[0,"Default",0,1]],[[610.8635864257813,343,0,769.8975830078125,447.7686462402344,0,0,1,0.5141104459762573,0.4852320551872253,0,0,[]],18,18,[],[],[0,"Default",0,1]],[[600,356,0,684,349,0,0,1,0.5,0.5,0,0,[]],19,19,[],[[]],[73,98,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`/@°+=*$£€<>%ÁÀẢẠÃĂẰẮẶẲẴÂẦẤẬẨẪĐÉÈẺẸẼÊỀẾỆỂỄÍÌỊỈĨÓÒỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÚÙỤỦŨƯỪỨỰỬỮÝỲỴỶỸáàảạãăằắặẳẵâầấậẩẫđéèẻẹẽêềếệểễíìịỉĩóòọỏõôồốộổỗơờớợởỡúùụủũưừứựửữýỳỵỷỹ","Sắp xếp các từ sau thành câu đúng",0.85,0,1,1,1,0,0,0,"[[34,\" \"],[14,\"|\"],[16,\"il\"],[17,\"I.:'\"],[18,\";!\"],[19,\",ỊỈịỉ\"],[21,\"Ííì\"],[22,\"`Ì\"],[24,\")\"],[25,\"(/\"],[26,\"[\"],[27,\"j]\"],[28,\"-\"],[29,\"°\"],[32,\"t1ĩ\"],[33,\"\\\"Ĩ\"],[34,\"r\"],[35,\"f\"],[36,\"*\"],[37,\"ẺẸẼỆỄ\"],[39,\"sảạăằắặẳẵậẫ\"],[40,\"kx\"],[41,\"Jhnuẻẹẽệễúùụủũ\"],[42,\"v7?+=<>Ể\"],[43,\"Faceyz0238áàãâéèêý\"],[44,\"L569_~$ẩ\"],[45,\"bdgopqểóòõô\"],[46,\"P#ọỏộỗỳỵỷỹ\"],[47,\"EXÉÈÊỀẾầềổ\"],[48,\"S4€ỤỦŨ\"],[49,\"Y£Ýấđơờớợởỡ\"],[50,\"BNRỲỴỶỸế\"],[51,\"DHKTUÚÙồưừứựửữ\"],[52,\"VZố\"],[53,\"C\"],[54,\"AÁÀÃÂ\"],[55,\"&\"],[56,\"GMỌỎỒỘỔỖ\"],[57,\"OẢẠĂẰẮẶẲẴẦẤẬẨẪĐÓÒÕÔỐ\"],[59,\"ƯỪỨỰỬỮ\"],[60,\"Q\"],[62,\"mwƠỜỚỢỞỠ\"],[65,\"%\"],[72,\"W\"],[74,\"@\"]]",-1]],[[1136.894897460938,1055.94287109375,0,82.66699981689453,75.98699951171875,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],20,20,[[0],[0]],[[1,400,0,0]],[0,"Default",0,1]],[[1136.535278320313,964.1973876953125,0,82.66699981689453,75.98699951171875,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],21,21,[[0],[0]],[[1,400,0,0]],[0,"Default",0,1]],[[1137.084106445313,1146.424194335938,0,82.66677093505859,75.98662567138672,0,0,1,0.5050504803657532,0.5054945349693298,0,0,[]],17,17,[],[],[0,"Default",0,1]]],[]],["Pause",2,621954870190361,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[600,600,0,1946.036010742188,1251.02294921875,0,0,1,0.5,0.5,0,0,[]],22,22,[],[],[0,"Default",0,1]],[[600,600,0,400,376,0,0,1,0.5,0.5,0,0,[]],23,23,[],[[1,2,0,3,0,0,0,50,0]],[0,"Default",0,1]]],[]],["Logo",3,899027236628199,true,[255,255,255],true,1,1,1,false,false,1,0,0,[[[110,77,0,195.7390747070313,133.4940490722656,0,0,1,0.5,0.5014662742614746,0,0,[]],24,24,[],[],[0,"Default",0,1]]],[]]],[],[]]],[["Event sheet 1",[[1,"Paused",0,0,false,false,881036884152158,false],[2,"DrapDrop",false],[1,"end",0,-1,false,false,348658772353398,false],[1,"isTimeUp",0,0,false,false,617056362802034,false],[1,"timeLeft",0,0,false,false,670843326082385,false],[1,"answer",1,"",false,false,538561721013949,false],[0,null,false,null,421297551205104,[[-1,12,null,1,false,false,false,438843515576193,false]],[[0,13,null,551138518888793,false],[-1,14,null,392038834754127,false,[[5,[0,2]],[3,0]]]]],[0,null,false,null,432411265738905,[[0,15,null,1,false,false,false,913106290597646,false]],[[1,16,null,260483465573520,false,[[3,0],[7,[2,"Load dữ liệu xong"]]]],[1,16,null,330854144982241,false,[[3,0],[7,[20,0,17,true,null]]]]],[[0,null,false,null,122100426567399,[],[[0,18,null,458181517098292,false]]]]],[0,null,false,null,495673204159818,[[0,19,null,1,false,false,false,157454832331304,false]],[[1,16,null,816803828558793,false,[[3,0],[7,[10,[10,[10,[2,"Question :"],[20,0,20,true,null]],[2," with value : "]],[20,0,21,true,null]]]]],[1,16,null,585706784629547,false,[[3,0],[7,[10,[10,[10,[2,"Request :"],[20,0,22,true,null]],[2," with value : "]],[20,0,23,true,null]]]]],[1,16,null,103090682922262,false,[[3,0],[7,[10,[2,"Options Count :"],[20,0,24,false,null]]]]],[1,16,null,460050924307031,false,[[3,0],[7,[10,[2,"Hint Count :"],[20,0,25,false,null]]]]],[7,26,null,227093858363506,false],[8,26,null,601277174090980,false],[-1,27,null,623599131030475,false,[[11,"isTimeUp"],[7,[0,0]]]],[-1,27,null,425755884896431,false,[[11,"end"],[7,[19,28,[[20,0,24,false,null]]]]]],[19,29,null,808593987399542,false,[[7,[20,0,21,true,null]]]],[10,30,"Pin",636254900159958,false,[[4,14],[3,0]]],[19,30,"Pin",210783341114782,false,[[4,18],[3,0]]],[20,31,null,756761854102448,false,[[10,0],[7,[20,20,32,false,null]]]],[20,31,null,843231659647898,false,[[10,1],[7,[20,20,33,false,null]]]],[20,34,null,429067541495196,false,[[0,[20,17,32,false,null]],[0,[20,17,33,false,null]]]],[21,31,null,312955471850139,false,[[10,0],[7,[20,21,32,false,null]]]],[21,31,null,725880314927928,false,[[10,1],[7,[20,21,33,false,null]]]],[21,34,null,588637745430653,false,[[0,[20,17,32,false,null]],[0,[20,17,33,false,null]]]]],[[0,null,false,null,278599510819277,[],[[0,35,null,505162364268873,false,[[0,[19,28,[[20,0,25,false,null]]]],[0,[20,7,36,false,null]],[0,[0,20]],[0,[0,1200]],[0,[0,0]],[0,[0,100]],[1,[2,"slot"]]]]],[[0,null,false,null,452078189778132,[[-1,37,null,0,true,false,false,488889777784546,false,[[0,[19,28,[[20,0,25,false,null]]]]]]],[[1,16,null,239886316843096,false,[[3,0],[7,[10,[10,[10,[10,[10,[2,"Hint "],[19,38]],[2," : "]],[20,0,39,true,null]],[2," with value : "]],[20,0,40,false,null,[[19,38]]]]]]],[-1,41,null,371942430718793,false,[[4,7],[5,[0,1]],[0,[20,0,42,false,null,[[19,38]]]],[0,[4,[20,0,43,false,null,[[19,38]]],[0,650]]]]],[7,31,null,933941275549609,false,[[10,0],[7,[19,38]]]],[7,31,null,380164134533232,false,[[10,1],[7,[20,0,40,false,null,[[19,38]]]]]]],[[0,null,false,null,698796573985720,[[-1,44,null,0,false,false,false,410553190492367,false,[[7,[20,0,40,false,null,[[19,38]]]],[8,1],[7,[2,"_"]]]]],[[7,45,null,847566670403732,false,[[10,2],[3,1]]],[-1,41,null,521667370636870,false,[[4,12],[5,[0,1]],[0,[20,7,32,false,null]],[0,[20,7,33,false,null]]]],[12,30,"Pin",361028315192679,false,[[4,7],[3,0]]],[12,29,null,466267976699500,false,[[7,[21,7,true,null,1]]]],[7,46,null,354611702724504,false,[[0,[0,1]]]]]],[0,null,false,null,848543107448972,[[-1,47,null,0,false,false,false,386888311054006,false]],[[7,45,null,590812225579568,false,[[10,2],[3,0]]]]]]]]],[0,null,false,null,822104816469346,[],[[0,35,null,737719939649407,false,[[0,[19,28,[[20,0,24,false,null]]]],[0,[20,8,36,false,null]],[0,[0,20]],[0,[0,1200]],[0,[0,0]],[0,[0,100]],[1,[2,"word"]]]],[2,48,null,256704970269789,false,[[0,[4,[20,0,43,false,null,[[0,0]]],[0,700]]]]]],[[0,null,false,null,441467613146144,[[-1,37,null,0,true,false,false,218190693390519,false,[[0,[19,28,[[20,0,24,false,null]]]]]]],[[1,16,null,901551014325770,false,[[3,0],[7,[10,[10,[10,[10,[10,[2,"Options "],[19,38]],[2," : "]],[20,0,49,true,null]],[2," with value : "]],[20,0,50,true,null,[[19,38]]]]]]],[-1,41,null,722355474670048,false,[[4,8],[5,[0,1]],[0,[20,0,42,false,null,[[19,38]]]],[0,[4,[20,0,43,false,null,[[19,38]]],[0,700]]]]],[8,31,null,424845902591780,false,[[10,0],[7,[20,0,50,true,null,[[19,38]]]]]],[8,31,null,732477610518970,false,[[10,3],[7,[0,-1]]]],[8,31,null,972534679995256,false,[[10,1],[7,[20,8,32,false,null]]]],[8,31,null,955022957314574,false,[[10,2],[7,[20,8,33,false,null]]]],[-1,41,null,820542104698850,false,[[4,11],[5,[0,1]],[0,[20,8,32,false,null]],[0,[20,8,33,false,null]]]],[11,30,"Pin",165265909130423,false,[[4,8],[3,0]]],[11,29,null,752256115955919,false,[[7,[21,8,true,null,0]]]]]]]]]],[0,null,false,null,391531229850255,[[4,51,null,1,false,false,false,541795463553529,false,[[4,2]]],[2,52,null,0,false,false,false,463624702778654,false],[-1,53,null,0,false,false,false,211208220731414,false,[[11,"Paused"],[8,0],[7,[0,0]]]]],[[16,54,null,933729384541080,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[0,55,null,256977907477815,false],[8,56,"DragDrop",500676445420163,false,[[3,0]]],[-1,27,null,392747038186299,false,[[11,"answer"],[7,[2,""]]]],[9,57,null,286145656469424,false,[[1,[2,"currentAnswer"]],[13]]],[-1,58,null,870335272692108,false,[[0,[0,3]]]]]],[0,null,false,null,131646557054595,[[0,59,null,1,false,false,false,891894169376380,false]],[[16,54,null,327930580854185,false,[[2,["correct",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[-1,41,null,202907159105342,false,[[4,15],[5,[0,1]],[0,[20,2,32,false,null]],[0,[20,2,33,false,null]]]],[15,46,null,145728902691754,false,[[0,[0,0]]]]]],[0,null,false,null,626804407280781,[[0,60,null,1,false,false,false,435087545862561,false]],[[16,54,null,217938364629081,false,[[2,["error-010-206498",false]],[3,0],[0,[0,-2]],[1,[2,""]]]],[-1,41,null,522820795913632,false,[[4,15],[5,[0,1]],[0,[20,2,32,false,null]],[0,[20,2,33,false,null]]]],[15,46,null,743250840849647,false,[[0,[0,1]]]]]],[0,null,false,null,138784311293898,[[4,51,null,1,false,false,false,318840334321068,false,[[4,5]]]],[[0,55,null,188346907636434,false]]],[0,null,false,null,144690028489488,[[4,51,null,1,false,false,false,961657910924384,false,[[4,6]]]],[[0,61,null,863067724909837,false]]],[0,null,false,null,339829265544415,[[0,62,null,1,false,false,false,425081282629100,false]],[[-1,27,null,357857564221621,false,[[11,"Paused"],[7,[0,1]]]]]],[0,null,false,null,619901953302901,[[0,63,null,1,false,false,false,453788771302771,false]],[[-1,27,null,986855891964228,false,[[11,"Paused"],[7,[0,0]]]]]],[0,null,false,null,678278685100726,[[-1,64,null,0,false,false,false,839154243379294,false]],[],[[0,null,false,null,203029406704081,[[-1,44,null,0,false,false,false,812877676162386,false,[[7,[20,0,65,false,null]],[8,4],[7,[0,0]]]]],[[-1,27,null,282958384255218,false,[[11,"timeLeft"],[7,[19,66,[[0,0],[5,[20,0,65,false,null],[20,0,67,false,null]]]]]]],[10,29,null,175097790282221,false,[[7,[19,28,[[23,"timeLeft"]]]]]]]]]],[0,null,false,null,978751838447749,[[-1,64,null,0,false,false,false,740586896137774,false]],[],[[0,null,false,null,539759871180422,[[-1,44,null,0,false,false,false,735943013123850,false,[[7,[20,0,67,false,null]],[8,4],[7,[20,0,65,false,null]]]],[-1,53,null,0,false,false,false,856670007560900,false,[[11,"isTimeUp"],[8,0],[7,[0,0]]]],[-1,68,null,0,false,false,false,955668488059869,false]],[[-1,27,null,302945892896402,false,[[11,"isTimeUp"],[7,[0,1]]]],[8,56,"DragDrop",118986934409651,false,[[3,0]]],[11,69,null,739058330936640,false],[8,70,"Fade",429052538282797,false],[-1,58,null,917300360080570,false,[[0,[1,1]]]],[7,70,"Fade",315915830094512,false],[8,26,null,585032189291227,false],[12,69,null,239984847558684,false],[0,71,null,474781657260693,false,[[7,[23,"answer"]]]]]]]],[0,null,false,null,365785861310817,[[9,72,null,2,false,false,false,466620429321609,false,[[1,[2,"currentAnswer"]]]]],[],[[0,null,false,null,780375794781622,[[-1,73,null,0,true,false,false,143001263185103,false,[[1,[2,"i"]],[0,[0,0]],[0,[5,[19,28,[[20,0,25,false,null]]],[0,1]]]]]],[],[[0,null,false,null,623354472074576,[[-1,74,null,0,false,false,false,929134158340487,false,[[4,7],[7,[21,7,false,null,0]],[8,0],[7,[19,38]]]]],[[-1,27,null,483299828391284,false,[[11,"answer"],[7,[10,[10,[23,"answer"],[21,7,true,null,1]],[2,"|"]]]]]]]]],[0,null,false,null,475666535596674,[],[[-1,27,null,374977936278745,false,[[11,"answer"],[7,[19,75,[[23,"answer"],[5,[19,76,[[23,"answer"]]],[0,1]]]]]]],[0,71,null,103117520878571,false,[[7,[23,"answer"]]]]]]]],[0,null,false,null,600608562107578,[[4,51,null,1,false,false,false,891500002256313,false,[[4,17]]]],[],[[0,null,false,null,426459896580949,[[21,77,null,0,false,false,false,811423894111416,false,[[8,0],[0,[20,17,33,false,null]]]]],[[20,78,"MoveTo",576994443738303,false,[[0,[21,20,false,null,0]],[0,[21,20,false,null,1]]]],[21,78,"MoveTo",664066818448917,false,[[0,[21,21,false,null,0]],[0,[21,21,false,null,1]]]]]],[0,null,false,null,813987173387856,[[21,77,null,0,false,false,false,360548133253360,false,[[8,0],[0,[21,21,false,null,1]]]]],[[20,79,"MoveTo",564863130284639,false,[[4,17]]],[21,79,"MoveTo",753250951346862,false,[[4,17]]]]]]],[0,null,false,null,398375489714286,[[4,51,null,1,false,false,false,723806263526938,false,[[4,21]]],[21,77,null,0,false,false,false,181942908228041,false,[[8,0],[0,[21,21,false,null,1]]]]],[],[[0,null,false,null,859972771487505,[[21,80,null,0,false,false,false,990148759371186,false,[[8,0],[0,[0,0]]]]],[[21,46,null,728229426682011,false,[[0,[0,1]]]],[16,81,null,436791612138112,false,[[3,0]]]]],[0,null,false,null,474877987440232,[[-1,47,null,0,false,false,false,904405232089990,false]],[[21,46,null,569169335937351,false,[[0,[0,0]]]],[16,81,null,898083323827850,false,[[3,1]]]]]]],[0,null,false,null,246743788520867,[[4,51,null,1,false,false,false,801931205987650,false,[[4,20]]],[20,77,null,0,false,false,false,551526414582339,false,[[8,0],[0,[21,20,false,null,1]]]]],[[0,55,null,135302385113891,false],[20,79,"MoveTo",959639910199972,false,[[4,17]]],[21,79,"MoveTo",258657396501857,false,[[4,17]]],[-1,58,null,387073202837793,false,[[0,[1,0.5]]]],[-1,14,null,357224634786112,false,[[5,[0,1]],[3,0]]],[-1,14,null,853002410411529,false,[[5,[0,2]],[3,1]]]]],[0,null,false,null,600080256108869,[[4,51,null,1,false,false,false,304672810310041,false,[[4,23]]],[-1,82,null,0,false,false,false,303482445048985,false,[[5,[0,2]]]]],[[0,61,null,684013340592645,false],[-1,14,null,519113282566716,false,[[5,[0,1]],[3,1]]],[-1,14,null,494131448394392,false,[[5,[0,2]],[3,0]]]]],[0,null,false,null,265453471250122,[[4,51,null,1,false,false,false,394936313563062,false,[[4,26]]]],[[16,54,null,625219449389702,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]]]]],["DrapDrop",[[1,"filledCount",0,0,false,false,528865922993012,false],[0,null,false,null,197106660861514,[[8,83,"DragDrop",1,false,false,false,528907557634308,false]],[[16,54,null,162558464641912,false,[[2,["click",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]],[[0,null,false,null,266963171745346,[[8,84,null,0,false,false,false,673397366023432,false,[[10,3],[8,1],[7,[0,-1]]]],[7,84,null,0,false,false,false,577869128870380,false,[[10,0],[8,0],[7,[21,8,false,null,3]]]],[8,85,null,0,false,false,false,609479521709627,false,[[4,11]]]],[[7,31,null,445026196152632,false,[[10,1],[7,[2,"_"]]]],[8,86,null,670463517581139,false],[11,87,null,538995332098798,false]]],[0,null,false,null,816493828433722,[[-1,47,null,0,false,false,false,390659514117980,false]],[],[[0,null,false,null,487754364377713,[[8,85,null,0,false,false,false,443159185077976,false,[[4,11]]]],[[8,86,null,774809908055048,false],[11,87,null,501986465343455,false]]]]]]],[0,null,false,null,946639210805430,[[8,88,"DragDrop",1,false,false,false,155941787306139,false]],[[16,54,null,361413524752870,false,[[2,["immersivecontrol-button-click-sound-463065",false]],[3,0],[0,[0,-2]],[1,[2,""]]]]],[[0,null,false,null,504792991445212,[[8,85,null,0,false,false,false,845450333794375,false,[[4,7]]],[7,89,null,0,false,true,false,204552588897544,false,[[10,2]]]],[],[[0,null,false,null,106550985509374,[[7,90,null,0,false,false,true,170480452496238,false,[[3,0],[0,[20,8,32,false,null]],[0,[20,8,33,false,null]]]],[7,84,null,0,false,false,false,938809230173413,false,[[10,1],[8,0],[7,[2,"_"]]]]],[[8,91,"MoveTo",350887864650832,false,[[0,[0,350]]]],[8,78,"MoveTo",122919247741976,false,[[0,[20,7,32,false,null]],[0,[20,7,33,false,null]]]],[7,31,null,568930528296173,false,[[10,1],[7,[21,8,true,null,0]]]]],[[0,null,false,null,101266177713061,[[8,84,null,0,false,false,false,148334850256636,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,31,null,762068200313175,false,[[10,3],[7,[21,7,false,null,0]]]],[-1,92,null,348122173801647,false,[[11,"filledCount"],[7,[0,1]]]]]],[0,null,false,null,296319278611324,[[-1,47,null,0,false,false,false,250133201929726,false]],[[8,31,null,116855994129968,false,[[10,3],[7,[21,7,false,null,0]]]]]]]],[0,null,false,null,180540551233675,[[-1,47,null,0,false,false,false,806523891610870,false],[8,84,null,0,false,false,false,831308228851461,false,[[10,3],[8,1],[7,[0,-1]]]]],[[8,91,"MoveTo",416883713281691,false,[[0,[0,1200]]]],[8,78,"MoveTo",572186182608955,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,370498434376498,false,[[10,3],[7,[0,-1]]]],[-1,92,null,250504698972287,false,[[11,"filledCount"],[7,[0,-1]]]]]],[0,null,false,null,664272208282422,[[-1,47,null,0,false,false,false,895425177786413,false],[8,84,null,0,false,false,false,246894625675163,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,91,"MoveTo",888826482377214,false,[[0,[0,1200]]]],[8,78,"MoveTo",393405307018971,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,503673017513230,false,[[10,3],[7,[0,-1]]]]]]]],[0,null,false,null,818745098688947,[[-1,47,null,0,false,false,false,929804756669469,false],[8,84,null,0,false,false,false,177859681995434,false,[[10,3],[8,1],[7,[0,-1]]]]],[[8,91,"MoveTo",449724002535088,false,[[0,[0,1200]]]],[8,78,"MoveTo",721292388859295,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,733212651291432,false,[[10,3],[7,[0,-1]]]],[-1,92,null,739300525987860,false,[[11,"filledCount"],[7,[0,-1]]]]]],[0,null,false,null,358120937494399,[[-1,47,null,0,false,false,false,416712700522674,false],[8,84,null,0,false,false,false,261187518957115,false,[[10,3],[8,0],[7,[0,-1]]]]],[[8,91,"MoveTo",431242330954619,false,[[0,[0,1200]]]],[8,78,"MoveTo",754072653542168,false,[[0,[21,8,false,null,1]],[0,[21,8,false,null,2]]]],[8,31,null,272960877861772,false,[[10,3],[7,[0,-1]]]]]]]],[0,null,false,null,580675938654997,[[8,93,"DragDrop",0,false,false,false,411147921527630,false]],[[8,34,null,610567804677855,false,[[0,[20,4,94,false,null]],[0,[20,4,95,false,null]]]]]],[0,null,false,null,622060364017684,[[-1,64,null,0,false,false,false,228576696549219,false]],[],[[0,null,false,null,108730370076990,[[-1,53,null,0,false,false,false,538413628199561,false,[[11,"filledCount"],[8,0],[7,[23,"end"]]]]],[[2,96,null,445242465744130,false,[[3,1]]]]],[0,null,false,null,218835501607731,[[-1,47,null,0,false,false,false,933470660702724,false]],[[2,96,null,797052197521566,false,[[3,0]]]]]]]]]],[["click.ogg",24620],["correct.ogg",60630],["error-010-206498.ogg",11425],["immersivecontrol-button-click-sound-463065.ogg",3830]],"media/",false,1200,1200,4,true,true,true,"1.0.0.0",true,false,4,0,25,false,true,1,true,"New project",0,[]]}
\ No newline at end of file
diff --git a/New-project/icon-114.png b/New-project/icon-114.png
deleted file mode 100644
index bf56364..0000000
Binary files a/New-project/icon-114.png and /dev/null differ
diff --git a/New-project/icon-128.png b/New-project/icon-128.png
deleted file mode 100644
index 523ffd0..0000000
Binary files a/New-project/icon-128.png and /dev/null differ
diff --git a/New-project/icon-16.png b/New-project/icon-16.png
deleted file mode 100644
index e1b785c..0000000
Binary files a/New-project/icon-16.png and /dev/null differ
diff --git a/New-project/icon-256.png b/New-project/icon-256.png
deleted file mode 100644
index 0916f57..0000000
Binary files a/New-project/icon-256.png and /dev/null differ
diff --git a/New-project/icon-32.png b/New-project/icon-32.png
deleted file mode 100644
index 02edf8c..0000000
Binary files a/New-project/icon-32.png and /dev/null differ
diff --git a/New-project/jquery-3.4.1.min.js b/New-project/jquery-3.4.1.min.js
deleted file mode 100644
index a1c07fd..0000000
--- a/New-project/jquery-3.4.1.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/