From 0ed565c88a451565986d999cf82462896102818b Mon Sep 17 00:00:00 2001 From: Tristan Rhodes Date: Fri, 9 Jun 2023 21:19:17 -0600 Subject: [PATCH] Starting from a clean PR --- examples/moving-saw-platformer/Preview.png | Bin 0 -> 200403 bytes examples/moving-saw-platformer/README.md | 3 + .../assets/9patch_Bordered Hud_all_32.png | Bin 0 -> 524 bytes .../assets/Blue player_dead.png | Bin 0 -> 714 bytes .../assets/Blue player_duck.png | Bin 0 -> 581 bytes .../assets/Blue player_fall.png | Bin 0 -> 609 bytes .../assets/Blue player_hit.png | Bin 0 -> 646 bytes .../assets/Blue player_roll.png | Bin 0 -> 568 bytes .../assets/Blue player_stand.png | Bin 0 -> 625 bytes .../assets/Blue player_swim_1.png | Bin 0 -> 654 bytes .../assets/Blue player_swim_2.png | Bin 0 -> 635 bytes .../assets/Blue player_switch_1.png | Bin 0 -> 648 bytes .../assets/Blue player_switch_2.png | Bin 0 -> 687 bytes .../assets/Blue player_up_1.png | Bin 0 -> 632 bytes .../assets/Blue player_up_2.png | Bin 0 -> 696 bytes .../assets/Blue player_up_3.png | Bin 0 -> 634 bytes .../assets/Blue player_walk_1.png | Bin 0 -> 617 bytes .../assets/Blue player_walk_2.png | Bin 0 -> 708 bytes .../assets/Blue player_walk_3.png | Bin 0 -> 699 bytes .../assets/Blue player_walk_4.png | Bin 0 -> 648 bytes .../assets/Blue player_walk_5.png | Bin 0 -> 589 bytes .../moving-saw-platformer/assets/Climb.png | Bin 0 -> 5231 bytes .../moving-saw-platformer/assets/Climb10.png | Bin 0 -> 5227 bytes .../moving-saw-platformer/assets/Climb11.png | Bin 0 -> 5153 bytes .../moving-saw-platformer/assets/Climb12.png | Bin 0 -> 5153 bytes .../moving-saw-platformer/assets/Climb13.png | Bin 0 -> 5078 bytes .../moving-saw-platformer/assets/Climb14.png | Bin 0 -> 5078 bytes .../moving-saw-platformer/assets/Climb15.png | Bin 0 -> 5168 bytes .../moving-saw-platformer/assets/Climb16.png | Bin 0 -> 5168 bytes .../moving-saw-platformer/assets/Climb2.png | Bin 0 -> 5231 bytes .../moving-saw-platformer/assets/Climb3.png | Bin 0 -> 5168 bytes .../moving-saw-platformer/assets/Climb4.png | Bin 0 -> 5168 bytes .../moving-saw-platformer/assets/Climb5.png | Bin 0 -> 5078 bytes .../moving-saw-platformer/assets/Climb6.png | Bin 0 -> 5078 bytes .../moving-saw-platformer/assets/Climb7.png | Bin 0 -> 5153 bytes .../moving-saw-platformer/assets/Climb8.png | Bin 0 -> 5153 bytes .../moving-saw-platformer/assets/Climb9.png | Bin 0 -> 5227 bytes .../assets/Energy Bar.png | Bin 0 -> 263 bytes .../assets/GreenHero_Fire_1.png | Bin 0 -> 7303 bytes .../assets/GreenHero_Fire_10.png | Bin 0 -> 8260 bytes .../assets/GreenHero_Fire_11.png | Bin 0 -> 8505 bytes .../assets/GreenHero_Fire_12.png | Bin 0 -> 8601 bytes .../assets/GreenHero_Fire_13.png | Bin 0 -> 8702 bytes .../assets/GreenHero_Fire_14.png | Bin 0 -> 8702 bytes .../assets/GreenHero_Fire_15.png | Bin 0 -> 8416 bytes .../assets/GreenHero_Fire_16.png | Bin 0 -> 8416 bytes .../assets/GreenHero_Fire_17.png | Bin 0 -> 8082 bytes .../assets/GreenHero_Fire_18.png | Bin 0 -> 8082 bytes .../assets/GreenHero_Fire_19.png | Bin 0 -> 6909 bytes .../assets/GreenHero_Fire_2.png | Bin 0 -> 7585 bytes .../assets/GreenHero_Fire_20.png | Bin 0 -> 6909 bytes .../assets/GreenHero_Fire_3.png | Bin 0 -> 7521 bytes .../assets/GreenHero_Fire_4.png | Bin 0 -> 7937 bytes .../assets/GreenHero_Fire_5.png | Bin 0 -> 7994 bytes .../assets/GreenHero_Fire_6.png | Bin 0 -> 8125 bytes .../assets/GreenHero_Fire_7.png | Bin 0 -> 8163 bytes .../assets/GreenHero_Fire_8.png | Bin 0 -> 8373 bytes .../assets/GreenHero_Fire_9.png | Bin 0 -> 8260 bytes .../assets/GreenHero_Pose1.png | Bin 0 -> 7647 bytes .../assets/GreenHero_Pose2.png | Bin 0 -> 6428 bytes .../moving-saw-platformer/assets/Idle41.png | Bin 0 -> 4379 bytes .../moving-saw-platformer/assets/Idle42.png | Bin 0 -> 4379 bytes .../moving-saw-platformer/assets/Idle43.png | Bin 0 -> 4379 bytes .../moving-saw-platformer/assets/Idle44.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Idle45.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Idle46.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Idle47.png | Bin 0 -> 4382 bytes .../moving-saw-platformer/assets/Idle48.png | Bin 0 -> 4382 bytes .../moving-saw-platformer/assets/Idle49.png | Bin 0 -> 4452 bytes .../moving-saw-platformer/assets/Idle50.png | Bin 0 -> 4452 bytes .../moving-saw-platformer/assets/Idle51.png | Bin 0 -> 4377 bytes .../moving-saw-platformer/assets/Idle52.png | Bin 0 -> 4377 bytes .../moving-saw-platformer/assets/Idle53.png | Bin 0 -> 4422 bytes .../moving-saw-platformer/assets/Idle54.png | Bin 0 -> 4422 bytes .../moving-saw-platformer/assets/Idle55.png | Bin 0 -> 4382 bytes .../moving-saw-platformer/assets/Idle56.png | Bin 0 -> 4382 bytes .../moving-saw-platformer/assets/Idle57.png | Bin 0 -> 4382 bytes .../moving-saw-platformer/assets/Idle58.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Idle59.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Idle60.png | Bin 0 -> 4358 bytes .../moving-saw-platformer/assets/Jump35.png | Bin 0 -> 4815 bytes .../moving-saw-platformer/assets/Jump36.png | Bin 0 -> 4815 bytes .../moving-saw-platformer/assets/Jump37.png | Bin 0 -> 4855 bytes .../moving-saw-platformer/assets/Jump38.png | Bin 0 -> 4855 bytes .../moving-saw-platformer/assets/Jump39.png | Bin 0 -> 4685 bytes .../moving-saw-platformer/assets/Jump40.png | Bin 0 -> 4685 bytes .../moving-saw-platformer/assets/Jump41.png | Bin 0 -> 5001 bytes .../moving-saw-platformer/assets/Jump42.png | Bin 0 -> 4955 bytes .../moving-saw-platformer/assets/Jump43.png | Bin 0 -> 5024 bytes .../moving-saw-platformer/assets/Jump44.png | Bin 0 -> 5024 bytes .../moving-saw-platformer/assets/Jump45.png | Bin 0 -> 5074 bytes .../moving-saw-platformer/assets/Jump46.png | Bin 0 -> 5074 bytes .../moving-saw-platformer/assets/Jump47.png | Bin 0 -> 5019 bytes .../moving-saw-platformer/assets/Jump48.png | Bin 0 -> 5019 bytes .../moving-saw-platformer/assets/Jump49.png | Bin 0 -> 5019 bytes .../moving-saw-platformer/assets/Jump50.png | Bin 0 -> 5019 bytes .../moving-saw-platformer/assets/Jump51.png | Bin 0 -> 5019 bytes .../moving-saw-platformer/assets/Punch14.png | Bin 0 -> 5003 bytes .../moving-saw-platformer/assets/Punch15.png | Bin 0 -> 5012 bytes .../moving-saw-platformer/assets/Punch16.png | Bin 0 -> 5012 bytes .../moving-saw-platformer/assets/Punch17.png | Bin 0 -> 4733 bytes .../moving-saw-platformer/assets/Punch18.png | Bin 0 -> 4733 bytes .../moving-saw-platformer/assets/Punch19.png | Bin 0 -> 4733 bytes .../moving-saw-platformer/assets/Punch20.png | Bin 0 -> 4568 bytes .../moving-saw-platformer/assets/Punch21.png | Bin 0 -> 4568 bytes .../moving-saw-platformer/assets/Punch22.png | Bin 0 -> 4292 bytes .../moving-saw-platformer/assets/Punch23.png | Bin 0 -> 4334 bytes .../moving-saw-platformer/assets/Punch24.png | Bin 0 -> 4334 bytes .../moving-saw-platformer/assets/Punch25.png | Bin 0 -> 4334 bytes .../moving-saw-platformer/assets/Punch26.png | Bin 0 -> 4334 bytes .../moving-saw-platformer/assets/Run29.png | Bin 0 -> 4502 bytes .../moving-saw-platformer/assets/Run30.png | Bin 0 -> 4258 bytes .../moving-saw-platformer/assets/Run31.png | Bin 0 -> 4502 bytes .../moving-saw-platformer/assets/Run32.png | Bin 0 -> 4503 bytes .../moving-saw-platformer/assets/Run33.png | Bin 0 -> 4377 bytes .../moving-saw-platformer/assets/Run34.png | Bin 0 -> 4377 bytes .../moving-saw-platformer/assets/Run35.png | Bin 0 -> 4614 bytes .../moving-saw-platformer/assets/Run36.png | Bin 0 -> 4241 bytes .../moving-saw-platformer/assets/Run37.png | Bin 0 -> 4410 bytes .../moving-saw-platformer/assets/Run38.png | Bin 0 -> 4468 bytes .../moving-saw-platformer/assets/Run39.png | Bin 0 -> 4718 bytes .../moving-saw-platformer/assets/Run40.png | Bin 0 -> 4718 bytes .../moving-saw-platformer/assets/Run41.png | Bin 0 -> 4559 bytes .../moving-saw-platformer/assets/Run42.png | Bin 0 -> 4559 bytes .../moving-saw-platformer/assets/Saw_Off.png | Bin 0 -> 451 bytes .../moving-saw-platformer/assets/Saw_On_1.png | Bin 0 -> 451 bytes .../moving-saw-platformer/assets/Saw_On_2.png | Bin 0 -> 444 bytes .../moving-saw-platformer/assets/Saw_On_3.png | Bin 0 -> 488 bytes .../moving-saw-platformer/assets/Saw_On_4.png | Bin 0 -> 459 bytes .../moving-saw-platformer/assets/Saw_On_5.png | Bin 0 -> 446 bytes .../moving-saw-platformer/assets/Saw_On_6.png | Bin 0 -> 438 bytes .../moving-saw-platformer/assets/Saw_On_7.png | Bin 0 -> 488 bytes .../moving-saw-platformer/assets/Saw_On_8.png | Bin 0 -> 468 bytes .../assets/Trophy_Idle.png | Bin 0 -> 561 bytes .../assets/Trophy_Pressed_1.png | Bin 0 -> 536 bytes .../assets/Trophy_Pressed_2.png | Bin 0 -> 536 bytes .../assets/Trophy_Pressed_3.png | Bin 0 -> 536 bytes .../assets/Trophy_Pressed_4.png | Bin 0 -> 537 bytes .../assets/Trophy_Pressed_5.png | Bin 0 -> 561 bytes .../assets/Trophy_Pressed_6.png | Bin 0 -> 561 bytes .../assets/Trophy_Pressed_7.png | Bin 0 -> 573 bytes .../assets/Trophy_Pressed_8.png | Bin 0 -> 573 bytes .../moving-saw-platformer.json | 29569 ++++++++++++++++ 143 files changed, 29572 insertions(+) create mode 100644 examples/moving-saw-platformer/Preview.png create mode 100644 examples/moving-saw-platformer/README.md create mode 100644 examples/moving-saw-platformer/assets/9patch_Bordered Hud_all_32.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_dead.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_duck.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_fall.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_hit.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_roll.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_stand.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_swim_1.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_swim_2.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_switch_1.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_switch_2.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_up_1.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_up_2.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_up_3.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_walk_1.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_walk_2.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_walk_3.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_walk_4.png create mode 100644 examples/moving-saw-platformer/assets/Blue player_walk_5.png create mode 100644 examples/moving-saw-platformer/assets/Climb.png create mode 100644 examples/moving-saw-platformer/assets/Climb10.png create mode 100644 examples/moving-saw-platformer/assets/Climb11.png create mode 100644 examples/moving-saw-platformer/assets/Climb12.png create mode 100644 examples/moving-saw-platformer/assets/Climb13.png create mode 100644 examples/moving-saw-platformer/assets/Climb14.png create mode 100644 examples/moving-saw-platformer/assets/Climb15.png create mode 100644 examples/moving-saw-platformer/assets/Climb16.png create mode 100644 examples/moving-saw-platformer/assets/Climb2.png create mode 100644 examples/moving-saw-platformer/assets/Climb3.png create mode 100644 examples/moving-saw-platformer/assets/Climb4.png create mode 100644 examples/moving-saw-platformer/assets/Climb5.png create mode 100644 examples/moving-saw-platformer/assets/Climb6.png create mode 100644 examples/moving-saw-platformer/assets/Climb7.png create mode 100644 examples/moving-saw-platformer/assets/Climb8.png create mode 100644 examples/moving-saw-platformer/assets/Climb9.png create mode 100644 examples/moving-saw-platformer/assets/Energy Bar.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_1.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_10.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_11.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_12.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_13.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_14.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_15.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_16.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_17.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_18.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_19.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_2.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_20.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_3.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_4.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_5.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_6.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_7.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_8.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Fire_9.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Pose1.png create mode 100644 examples/moving-saw-platformer/assets/GreenHero_Pose2.png create mode 100644 examples/moving-saw-platformer/assets/Idle41.png create mode 100644 examples/moving-saw-platformer/assets/Idle42.png create mode 100644 examples/moving-saw-platformer/assets/Idle43.png create mode 100644 examples/moving-saw-platformer/assets/Idle44.png create mode 100644 examples/moving-saw-platformer/assets/Idle45.png create mode 100644 examples/moving-saw-platformer/assets/Idle46.png create mode 100644 examples/moving-saw-platformer/assets/Idle47.png create mode 100644 examples/moving-saw-platformer/assets/Idle48.png create mode 100644 examples/moving-saw-platformer/assets/Idle49.png create mode 100644 examples/moving-saw-platformer/assets/Idle50.png create mode 100644 examples/moving-saw-platformer/assets/Idle51.png create mode 100644 examples/moving-saw-platformer/assets/Idle52.png create mode 100644 examples/moving-saw-platformer/assets/Idle53.png create mode 100644 examples/moving-saw-platformer/assets/Idle54.png create mode 100644 examples/moving-saw-platformer/assets/Idle55.png create mode 100644 examples/moving-saw-platformer/assets/Idle56.png create mode 100644 examples/moving-saw-platformer/assets/Idle57.png create mode 100644 examples/moving-saw-platformer/assets/Idle58.png create mode 100644 examples/moving-saw-platformer/assets/Idle59.png create mode 100644 examples/moving-saw-platformer/assets/Idle60.png create mode 100644 examples/moving-saw-platformer/assets/Jump35.png create mode 100644 examples/moving-saw-platformer/assets/Jump36.png create mode 100644 examples/moving-saw-platformer/assets/Jump37.png create mode 100644 examples/moving-saw-platformer/assets/Jump38.png create mode 100644 examples/moving-saw-platformer/assets/Jump39.png create mode 100644 examples/moving-saw-platformer/assets/Jump40.png create mode 100644 examples/moving-saw-platformer/assets/Jump41.png create mode 100644 examples/moving-saw-platformer/assets/Jump42.png create mode 100644 examples/moving-saw-platformer/assets/Jump43.png create mode 100644 examples/moving-saw-platformer/assets/Jump44.png create mode 100644 examples/moving-saw-platformer/assets/Jump45.png create mode 100644 examples/moving-saw-platformer/assets/Jump46.png create mode 100644 examples/moving-saw-platformer/assets/Jump47.png create mode 100644 examples/moving-saw-platformer/assets/Jump48.png create mode 100644 examples/moving-saw-platformer/assets/Jump49.png create mode 100644 examples/moving-saw-platformer/assets/Jump50.png create mode 100644 examples/moving-saw-platformer/assets/Jump51.png create mode 100644 examples/moving-saw-platformer/assets/Punch14.png create mode 100644 examples/moving-saw-platformer/assets/Punch15.png create mode 100644 examples/moving-saw-platformer/assets/Punch16.png create mode 100644 examples/moving-saw-platformer/assets/Punch17.png create mode 100644 examples/moving-saw-platformer/assets/Punch18.png create mode 100644 examples/moving-saw-platformer/assets/Punch19.png create mode 100644 examples/moving-saw-platformer/assets/Punch20.png create mode 100644 examples/moving-saw-platformer/assets/Punch21.png create mode 100644 examples/moving-saw-platformer/assets/Punch22.png create mode 100644 examples/moving-saw-platformer/assets/Punch23.png create mode 100644 examples/moving-saw-platformer/assets/Punch24.png create mode 100644 examples/moving-saw-platformer/assets/Punch25.png create mode 100644 examples/moving-saw-platformer/assets/Punch26.png create mode 100644 examples/moving-saw-platformer/assets/Run29.png create mode 100644 examples/moving-saw-platformer/assets/Run30.png create mode 100644 examples/moving-saw-platformer/assets/Run31.png create mode 100644 examples/moving-saw-platformer/assets/Run32.png create mode 100644 examples/moving-saw-platformer/assets/Run33.png create mode 100644 examples/moving-saw-platformer/assets/Run34.png create mode 100644 examples/moving-saw-platformer/assets/Run35.png create mode 100644 examples/moving-saw-platformer/assets/Run36.png create mode 100644 examples/moving-saw-platformer/assets/Run37.png create mode 100644 examples/moving-saw-platformer/assets/Run38.png create mode 100644 examples/moving-saw-platformer/assets/Run39.png create mode 100644 examples/moving-saw-platformer/assets/Run40.png create mode 100644 examples/moving-saw-platformer/assets/Run41.png create mode 100644 examples/moving-saw-platformer/assets/Run42.png create mode 100644 examples/moving-saw-platformer/assets/Saw_Off.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_1.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_2.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_3.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_4.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_5.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_6.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_7.png create mode 100644 examples/moving-saw-platformer/assets/Saw_On_8.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Idle.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_1.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_2.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_3.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_4.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_5.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_6.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_7.png create mode 100644 examples/moving-saw-platformer/assets/Trophy_Pressed_8.png create mode 100644 examples/moving-saw-platformer/moving-saw-platformer.json diff --git a/examples/moving-saw-platformer/Preview.png b/examples/moving-saw-platformer/Preview.png new file mode 100644 index 0000000000000000000000000000000000000000..44c9420d83952403881f6904ee45cd5a3da8b4d8 GIT binary patch literal 200403 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

GmJ(+5gNJ;~lA(Y%h{su=Yv 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 e6QGVK6@c0000anM1_s7` zo-U3d6}R5rb@Xd75MfKudvIy0clj~r9UuAToiwgw^lz0EKI^bx>8)=EKTO<{5?1@< ze_8@Zt`*PAKfnFCJl5_zpX!SG$RGCVHx@l(-10{B?tYeql^@bs zA{sh)|F2=tY{~gCee#-E-Q#`l;=49*6M_}WUi|asaAokm-xK%nj@Q#V*4Yd#@#2g?f8hcL;usaK z)a%nHpiX2bQ=DVGvMbU;qXy zD?c?Hda~u=6>zgh}J@R3=K9f(ne`6_7@?tUj-|qgvt-SxZU%WD&n0D;^Es))wu6{1- HoD!MRA}DqTCq;UFc9q@Kmh?2ZKHkxpTNSvfCK|05)2G1s7N4z zK&UMRF|shRR7{Lr*ccEyDryRIKY>pOJ{OA+>ZDF==j_DN4TLrAD?b<3Na>NCL8AK&3zyNm#w@(TP zkg*-!LEJql7|bdycf)8fY8Sm_SzwI3WH2>2pUWxA|$m^USk(Q62y}7L$Z+`pEbDBMBrTs^GZt3ue z&kq9Y&`Jd3h;(NC%$r_4pf~m_CwpD$LK5hm zVPP@o?!j#!dmS}WVWSm(7WW?h?0qm6K^AuJrLRj>NQ$GNYs+AD6Rd3EM@5~Zm0)$& zE9mPSmBNp7(?PHx&X@v-mO4kqCk36Ro=^<}LyP`u8X(Gf#H1|)_nPU1EEQ7KEfX4{ z%$pE;wSK#ygq8C^73R@s zsiI)SRmQ2JAHi4XK#A%SN=kB*kT@z(bTEDtD5!eSbcMe#P*4FfF3PCN1$dyK>IC@d w80z}7M3uR~=z6~|!TO%~eB>h^`7m{S141CGsDCh3nE(I)07*qoM6N<$g2!t)zyJUM literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_duck.png b/examples/moving-saw-platformer/assets/Blue player_duck.png new file mode 100644 index 0000000000000000000000000000000000000000..e6aca27db56181887746686fe97bece53c17a02f GIT binary patch literal 581 zcmV-L0=oT)P)91tFF3E6tHG1_#7WQOIg?#R77Mr*}q~V#JY}Px-#%v z4O{wjP~}f*AE#JtzoY6?Foo76OQ|x9bRWuOXc2;8Ja;;<<@TQ7wSgC1X8gVY6k?nZ TzTVCP00000NkvXXu0mjf&jI=O literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_fall.png b/examples/moving-saw-platformer/assets/Blue player_fall.png new file mode 100644 index 0000000000000000000000000000000000000000..f85f007dcd8741afe6a03a1ea1e83872d644141a GIT binary patch literal 609 zcmV-n0-pVeP)mKsYiBiSc7mRA zBTu=(v+YI?WuA3*L87ZyA8|J9i||(Wtg~x8;WTv51P}p401-e05CKF05kLeG0Ym^1 zK$>35PPh(}DGX;n4QOpg`nhlhI13pNFs{R>jtzhwpvZ%>p#uWn2sbcBwgI-60zL&- zFwnges8jA>q=CXIoJ)nIbd(!@ngR%%l}t-;4FLoj5R*y<2@rl_tVpD_-({SjCv7(` z*$47=WY&rkZgOw8i>JOqmG2ajZ3RJgj_+-p`D;u|Wk53Ravk!ZoQXXVKDq?TnA|bb zwPDrw>=$hfbt*2zGw&KAzk-{1!_GPuk?F?js@6Iv&Y*QfcS_ zsj?5smW)WN`Xm^DK-sc$-+v?6*`1qQQos#5K+5i8L8Jw5$x*Hip1j1rD_yZ7NuG`Tl0yoi7L_qm3U^j3iX! zhr5wPV*GG6l32|ve<9eWj328js|kWNl1SS!l333x6!$sC6KPe8pz}mpSUN+M`7bm_ vMZxB=`AHO~sW|z=Vdjm2)|!At=y7}j&N5@j{R3V~00000NkvXXu0mjfR_6zI literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_hit.png b/examples/moving-saw-platformer/assets/Blue player_hit.png new file mode 100644 index 0000000000000000000000000000000000000000..88af0b8fe3eb88d638e965e7a626bfa9890e8031 GIT binary patch literal 646 zcmV;10(t$3P)@& zleoKdbkoIM+@;b~=RSgu5c7`&YTM-Ao8Hgl95_QtF1h#D^PSXcBqSsxB<@T7vhOv6 zVY_)9K6t_44H{qfn%%+S()q_irC`Jd_glB$QI>i^_=9^Y0Rxth2V-1eF=e-m9xseB zDD6_h*zAVeqA*hTDP>IYZoWQ?07#Dz%rf)A8zTjFpjO1_=rjP49ABVZm3nSG=H{2E3m$CXG3kv=vSup;rWH_39 z&MX+I@>sC4f@&5Nk(xsw4f{MWv;bkH&T%L*0%=}=Wx>#vu2~1gCb40dw<;hAnk*Pv zf+{x@30b8$EX^=v))u9KVIvgdFu2{P(~s6qo}<-+`$RX+Uil6vu+AD7JW%S#PtoGe z=|5dNdSqu3&UMzoV72zkd!4C+L0LdV)+w(yiu5;GnI%2Q%KlxVyg)?OX(`iX4SpII z?^D0=#1YYTa9gJbKPs|}6@#RC20zmK9Mgj&%sXu>&WvRoS%V+>u9H7VvTA~^&2@AK zSlNRg1>NvSYk*ZT_)$4Xs$7?AG{7bkZAXA;c@=77X310a0o5TGT3&Fu21I!rami({ z*Gd;;MuMs>-7Sx58yvZida*~njh#hpKkvI{}M{P)PbXFRA}DqnmtYfF%X4w13>%<1X<+-9D#-&3JMA&C@DZGDG(yd zf~XJ;6%8dFIYKUg7VQS=9DyU4eF&ov9I-#%%-ESHxr?RvThE)Z$Bl+aBoc{4A|Ew( z`ZBW~rrXV^e-T7UZ~W+Y@f-ZsOAu>ex|uETv332fijE*kKbn{6-O5=UcmX1~dV4Jc z!VD+rISB@#fo*RKglWe(1EX~wZ)7kAb-)mOme1jT>&OR(m7H-c02n#c>=U4nS! z219!Z2@tqCM<8Sw2f3ds5L_Khb#^hGa|nQxKeGg#SgjsEtHr%rwXl1mmiF(h&Li=W zN~!VaNzHDZ{2I%L4_4aoAbza9k6DkUDI#a%-A}Xs&it`uDY`mWzGHh~ z-@XnW9B=Xt!9I^|cXG6J`LSTN>0%2Xc5lDqdEt1$4}7N;Fd!51U}OU_#`Me>mxYmm z(l-*umK*F;g^_L_BQ?dj`TFDml4J=JUbD6eJ2`k^qyeXr5ilU#A?@n|0WmfsJ6O8c zg^|X#8|(b8jmG$KMt;0;_7bli z-Y2nn@m6k;6~{p#h(bs^r_b@??)k4+JAN##Mk|ifMqrDKpXL40pM^mb0pS^^+(-hy zvuI)eEvgI<-f_@jYi<0j9Nckj8QyWqjHI#-I*22PV!EjHlc!kZI3)txwDBXN&ygyy zGW!+n`y7$RPvap&V8NWh0z^umqq0Qj3Gsr82!<5@6&n!YI)Z7-z+AN{$XX++vTZ^X z#u0|2SL%N^Nn=;zeGeH9nsjdj9;l<9z?_sCMevG(4!sS`0p05odDWz{N|S&P5CTF# z2nYcoAOwVf5D)@FK#F~oXr8N;chB4m8Th@dj{+TP+N$T>lX*=6AB|fi3SVvS00000 LNkvXXu0mjf1V9U9 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_swim_1.png b/examples/moving-saw-platformer/assets/Blue player_swim_1.png new file mode 100644 index 0000000000000000000000000000000000000000..772d4e7d5c11dab490f8a5119fcae7f36d66b3ee GIT binary patch literal 654 zcmV;90&)F`P)@0|#h0$Pz6w{L0c-fIaQ3#C3K;N$C=k8oU4Fc0Pu@JMVc@QNWxtsOqYLE+ z9K6ZF2t%nl7>rr9b$DU?2HB#65!yEOnuEa@>EJ3F25h0^uR0h^vgTkgISIiGR1S=; zQAy|XrTV5+5P#cd&%vOSwW@^CF$aT!{OW?yiX#{Pt%G5z{OX2b)aiFr82QteU}obc zm|nkbS$6xLd!BarrTi#)O7fXz+Mp6Mv9g_m3NTrH5HYo oIGG(-P^#D3)~KfDl`$K}H;}9t_;y6nfdBvi07*qoM6N<$f*8{?1^@s6 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_swim_2.png b/examples/moving-saw-platformer/assets/Blue player_swim_2.png new file mode 100644 index 0000000000000000000000000000000000000000..22c3bdb15d26e48751b706dd546f1f4dbeb703ec GIT binary patch literal 635 zcmV->0)+jEP)~%7c9x86u&^;8HU?DG6lNZwj}ZE=N=Z^&3U+Lt<48AER^^}X{e<7o1g{b(U+ zP7%Mcy_XR;XogFF2u z4ljm>P`a<7w~ej!{!3aS04)aIr)u7#|Vo_=v{r$dU>CjC+X0*$jkRCT}j zGyQ=?Epnoow@I5AK-#4ML~8n_;3b$6kX?_2HvJNVqGa+2y@Rf)SlK9+uAZU{h^`)@ z>;`SvVhxQK;N||3r~0x8I>G{ga6)g9JuN&xB7NuOUCQrQ0Rqk2@j2pESebH1{{a{tMMb?kd>cL%Tsf3q~Wf!L`sHW$3&Xtx&UF{Js{Pqs4yt>&~&l7 z!Ket6K%^@A72%`9I%$-`Ptc2twbPek`QW~^ z_4C(4l^+y>=!mp+@?6aCoc*wsqemrv)(|X@@Uytr`?WDJRep^NNuYP~ob|spH4PwK zeyqbrBm6Aw-w7QV9>2zfBoPH2$Pq}f+SKatlNLYY1gl#3(b4A^C0LXFiuHYtPT|LV zBqc-X%mm^L6+o15PLn0NP7^0of?&)5Q7Iu%J2F75QYl)bAVc}j+bR>H5RNdUUZZz6 zWn(8X?_okgGp>!m58B8l@J@{iMKGdZLvI7`fM#5xPDrv&95#4gGaxnEAg!O&g?dwR zpN*A3L2_!GWU2{0fNCV?>=kTKjdqcbfS zL!dNSg0a?)H)X*n%7-PV_*d_5Du85JB8Zn)sfd$96^tU_RAK=Jq&uX2SwMh{d1Qx3 z_p)FVvEGiiNrTb2h&Hgm7-UI5Ax*F{J%_|G98{J_*%0i2Nc)K{K*Vo%S!orFfJTpu ziq#E9L9mr2QnCcAs#nyr#BrUYlSs)~1SW`-48a1CV(1m+(h*9Ur19goqIBi>DP7#V z&0_WRImKEBjUYK9tsgz6vs)+MV(H)>Wt}qwD`Wi3@3ekx3<7JNbt4J4z-dgW=*sm!zvA#E4_)9Y%y&U;sYak zDD2~y($PEVNJcB8OxTr}_i&0|uyhZA;v%2GJ3(1bD=z>P)batMazWd`JNzWg!Mpu^ z6X1-IWWpTIGdY;lF4(xQ>Ds<|%Lj!!PMFhH)#!+}0saUGD-%iM`WAFDBQqK?X2y*D zl(OtKg))F)L?5V_b%d^wIIouO*o#-EOV`~Mrul5};hJiF@# zgYLEeV7t?IDDryJb*4v4mmdpOn=Uf(QSbIU$}8LTf8aB%fB~IQ1S4J0F}ioggce2$ z%0NpPTaLfO3L{xQT55`Y^YvK;NZchvc=cK;Wap>~BPrOGw15Ha4sBl-2#B#B-9g&D zE{vqM9e)osjNZ`eHw9zfB|(TrQiNLm2NYM&xmS3^QUbJ!c60IKI$F+I!M%Mup>n}0-+=X zM1|;SA}Ts)=(zw2$_DBjfg>!QL`I8PJ8Q2$Gv2i{1yUT=FXK1!-cGINY1J?KQKLIN zZCu6oQFrhL!T#Et9kR4h$8C7-|(4IfB~5x10x-fF`;KhFE1D= zP)>scW33Z!s)E6?lMs~1t zFA4^a^-jD^8jR*;f5Q|QlPnpINE56|&!JF;Tcst^U1T=ai zz<_kN4F)IJ(h@0Ig3Zz^QM;e496u+Edw1hlJ$ucU0Xg=e*Ev~4T0eS9X17lM#L~gT z^h%O*A6kn*M5OaO?SBV@m=p8BMJOYEMWWwQ`n@9AM+ioCnHJ6L3eg_TobHm z@9 zRo$@$AK}b6qELFBzPlL8tU(QyOl-1{;8=T>7JSRTevO9f6y|?Ps es#dkCm0CaP_zq(MgQgw;00000|Nu7Yzzps zp&%y2&QdY4!NSf9prR%)_Yru6;A?SJLP=sbXZzCoq#Gi|lKs==^ZA@gg~f7G)$@+; zwW7Lr8Q%G=?kj|NZhJv@f9~vUW~yL_g*R%~pYea;x56)YXDVPoCZxd_4ak_XXGS|O zj1egHQo>jZ!cA2e^7ARBr}$SN?>a#GSt5+LT%U^AIdoyjfL*B+Fd*F_?I#5SW?YW! z5a~WC3>oV|xJ?>H?V__$6pTTZL_N|5t5S0)Y{PC9Y(FJ;0|K^EOe0k>Sja|s1Q40@ z49{i^GO>Nab25zwMjG|7fWU(D%*)ytBnc(!tWreC>>LLp`Hq!CnS=uAj16PdVABdd zbRb#fH%t!0NYl!C>m|RcS^CXRymI^$FYev;WA*d}b=(k?2~*X9QayT%XSYs%#nQn& z+BoAdRH4l8H2*9N0%M#t7%EW4Eh-NX)p6Eg5s^gq#BxUYA!W_XA<)W4k zA99bmIr>oI|?t zL$;BG+4v!8u>Ecn5geNKc4kinj%Uz@qU_pyYI!GXX$EPM1DI= zdhN^j&JV}0Q0(=n9gGha&fn&|CS7degUXKaZ*$KtB-dXAbFQC;dN`Nu$@B|1~1r^oPYuC4sBl*2#B#8-ND+u zDhytmLA-++MyDTjRl%5aNs^)#SdlY_z&1Q+tdKe*uoEFoQe8mUcRxGjRa6ul^iaTn zcGeAp3v6SB6s^F@`W5*uskzV5DWvEk0uw@tMqoimRrnR@rNf*w%HYQzM%miQQ?|T+ zo7ei;OQvcZ90bt`Y3ukgo8LbDQ7eb{O2*YjU`2wT#oghri9x9vXFW)Qyi;VY|23&u zfC!Ca4jWDIv$S_3wPZxbSqqY65_Awp5Jf(z)uRV3flF*&oL^nCjCn7eU8rH zM|qhLSO{mZ05RfoY#z~NO242Yf?*_o#Rf#Xj$m3caIdvIkU1@?rei`B!4Zb7*XVyY zxv{J8yoZSd&3HBfKUhaSfqSwV6u~13b?`QD59l73C_7DBJ82RS0zyCt2mv7=1cZPP z5CTF#2+03AN;)moDtph}4(UhTVvYh1m0R_)_e@^j0OMOEQvcb100000NkvXXu0mjf DjpYXh literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_walk_2.png b/examples/moving-saw-platformer/assets/Blue player_walk_2.png new file mode 100644 index 0000000000000000000000000000000000000000..feafd206f910478244cb0fb201f4cc3daa141040 GIT binary patch literal 708 zcmV;#0z3VQP)t0jSlMY~?+X|Vht@oTk8tcjHo=ntcG;cVne&n<2rS%wH~Z~;-wuVs{}sknylh3K zMyFD`jvt~%`yE2PZkFop!-b2FxmvqTZEtfiuM4qGsEz^)_$3`loK`&j`2GM14Y zD&1!VL&s)4-enC&`Kq<$3XDOPbh@kw)}-bz*oLdQB~md2J0Q|d*B2n_yI)0V6&C@8 z9vcM9PL>fk<8G73-y=lr&4@C#toQwbPem z`QW}E>*sHYt8q{WvLn*s$#XKlbM`A%jvk$i3x;4#jGx85+MkI*xEhzakpzCH$yy&Z zsc8T)8mAOC8{=nb|ITX3n2gKJNV0LzfgFJp^`ushpS+ACCs^0Uj}M(gO0blAC3v0V z)A(^76a)+A3>QF1bWWBfx=r{eR7PNs_^;dm@y;WhmJHl$kOi4&Ql+*DSr|tgwqDY+ zo4&A{q2GhTK_mA@;0HtG6S${LjUs4K2tnJxJ+Nw*!1_eAR7c;J+KGs9j!tiE_hNHo z>EgUMeSDCqY9(DRh-HxWEU@idT(2s+8>OB+W?HlB2eHvVqjbhNYf=mt*d(#1jvbh@ zX^^o!yTP1sY>g$CZ#`C#IffQ>}gNZ q9B4bZgaR%7w5KV>M^&~|wMY*>qF!YkW{#Zz0000kf1JO&@AK7avuE}=`P46a zK_eQp8rShd5cS_7*ynB|>>n;%e9Tn}47Txh^Y%LtMG(b5@HdqJ12RDdMm8X0e9w$- zUNADCw7djkBaF9I!QjWoOHK)HzCLvTNwb6zuU|)nRSsP+ctBP10t`rZNc*CI02%v{ z9W338g27`mjCV+C4(Vpf>r4`6v}YBvP9|)!H$V^Fth~-`|ek-w2Fy< zMvsh&wG9R**vb+qS%THoEBaaDxX!Ujq~t6D3?d~%ut20H^osV;VM>~$@e_1<$=c~l zvV3r##`^hNVrm^Ug5-#_e)62m@0|ULm7_-^>zpB272{`duk&wX5T@3ZZX|)?pTIknY81hUf(zOP-hsrpgiQPVB|VvQPv+`U*F+MPMA6+2 znX5}_b_k}203=aM4QcP?h^EX$n&wrAIEnO#rg&4+Q(rbgKypM=miBqcQAV(&CWvIy zLn_^){CfzEXqx=bs+4SZxkJ#>>zckrxX6v_V)$A>RIO0F4qMfwXiGh*pCL1^%0(Y1 hL{lbB_9)sEa3jNKR(`gUHY@-D002ovPDHLkV1mXxHsJsO literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Blue player_walk_4.png b/examples/moving-saw-platformer/assets/Blue player_walk_4.png new file mode 100644 index 0000000000000000000000000000000000000000..7230aa6159dcec1dea67ebb176ee066e7503a2fb GIT binary patch literal 648 zcmV;30(bq1P)-RK1wu&( zhziluL{xOp&~pJ4lnvB50!P^RZLkyqL~Cd4^>{tf6p`X={C4Ke%(F|SV8McMu=05) zsPKhQ8{$MkdCV41sDi-g#EODfQ-&qk7TVpaNqUCA~gtf>r4`6v}YDute$&!48SE*Ea=-`0Zz}W)%uY zqsL~7H4TO&*uoMiTY}Y{SM;OA@j1sNk+PErY!E3Mf(4OM%q!ZdBPMBQE^>Z_+O3Dr6@g6xR2eDs*iZk_z_rGtBtbmD!KmG zrm_H{v`$ReY=obM-5afxQCXLpkffuagB(GMa#PEP4@TBmCs=CX$Hbgtm0)eoE6&e3 zCWRkzw?VKFXSe`jWzNa7Mb~ljgvtmEEBY%pK#cPUr-RK1wx52 zhziluL{xO7q2~g~C^pnN0!MImY*|Va8+q5e_Rj7+X$qul@IKAFnR#)mMIaCe2+_F- zT*r@k&RzKI`r}Us_V>{7#wRP+UrSbz!7kqKKK#Z-;rihpe8vhgAQS#0V>TdTOwWvA zSu$ow=^07JwioX4l982#R%)>?^{h!!~J@#*aG);?0Zq zc>VY(iLI-TSk^fh1knj;=lm^R-oKoS_UVh1bJ_?jkMXm5I9RwCgsgLo8%f}I^3;0X zrOFV(b&hS=XpEn=qer2V;W;PGNJ=|JG^*l#mJvq~#q3fWXRk`nm2u$;%ZxYuO^VzO zr7|-x#G>72F&Vjp)VZZVNk@|6ay z#1gwrh{8C65numusqwcP-CHy~TkYNm{6ih}1fHo;qX=G6&|%7jXF&hD1c5*x5C{YU bfl!Dk!La(#`6%MP00000NkvXXu0mjf!AAw0 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb.png b/examples/moving-saw-platformer/assets/Climb.png new file mode 100644 index 0000000000000000000000000000000000000000..2239b4293b7ff20ceaac5a1c8823a506fe4f2f18 GIT binary patch literal 5231 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb10.png b/examples/moving-saw-platformer/assets/Climb10.png new file mode 100644 index 0000000000000000000000000000000000000000..aff2199b28a587908424c3c2e3a6d9ac4d4e73e6 GIT binary patch literal 5227 zcmV-x6qM_UP)z%eh$S)R*PQR{bKiUOW`M+eA!H5n-dbld;0(;%efQqy zoO|zczyRyAF6*)`>#{EEvM%egF6*)`>#{EEvM%egF6*)`>-u*tzmo|RbR(U7PbZM) znki(B$bWR%4lSUN)&dG{Tu#CDxfJp!k3!oEDd7853zWXTJW3-el))H$FPjF}aNN(K z!4GmMxON$XQbfMT;w@16^78*SSpjh;iw57#(ty!Gsar-NEd>@JeR&1_oIydiGF9Bp zq`|*vpxjq10U+K7=2@Wh)fLDl9`y6aDsE=jK>=%+B_R*<$nV@@3y?kogjr)Dz*qQ&Sc-03ON-v@ zro>mfXi>)wN_hGS#XsFnaZk3<{3lyzZu=&RdAxyUwymS7EeuL?B~5r#L1Q15(Wr-| zG_s|XMm#N}Va>%9aHwld;dg#9`G2#7{4XXeP{5Sy3<_An%z%#s_7^|`E+qZmA0(!J zEiL(dFD1X&O(`9_DZO(qecbsOWpwV7uj$YCQtIByreYe_R7AttODLkHh-}-VjrZlx8I<3dM8a49i%9~C_=>P3Q?e}> zy=&+8JhMU{7fOZ_(v&AH3Eva%R`HHGnof&;+eOJQcguihz1UC7Uw%P_uMSi3>m#({ z^-+mpjw1e9-pem3yYm30F+hpWc2I2lW}4Nuo~AHcCNx(lP?}0;ID;~@v4|p?3Teob z5(>JUN}lDD$@h4?ic^aeD3_9ybTLZ+1bifj4c>K4m+6mIL~vcMRJzFJG0Q@lmXrUP zKhNi<-zlR+mZv2hJB0x`FFt1=4pHf^$Ef1BuW8MjQ&jclv=M85J4LI0J4t1~9v853 zUmg??<52*UQ6+;>_2vw%|NR_Q|9+k}zWs(aao{VyU;q1A0jT`f6T+m7&i%BAWh~}#HG{I6 z#xW?PSh|Kcf+ft5#sUgsP{JDXIPxj*YAX30j3wVA3&{^mxuCIx(_OF~S(i(KVLKKt ztp;HS55DNH28Mh%{$PW)M0fdcGapvb{LbyPkc}F$lftt+`^5n&V0Ns0eT-H!6V~yd zSHC?kKx}?{fwo9ol)(4+`344TH8Td1mc^jJTcTLLCbq1iF^^WVmoQ5pTMY%mlCXw6 z3grl4U;-|ukk97~%2#p9Q@%}>+5~_EUUSi|FQ_doYz9QSrgt?kSdaBwf6#VEKqlQO zrMWM*(%i=zC2PVUE@g&fvs@LuIwG?kvmb+Pfbqvg+UgWKFklR%3?2jXU+`qB7(Jv5 z2CrlbfB+2kxOx?M-(ZFfO!+!NGA}R(pDFONi&p9(kMfmVfgO-4d>Cd1z|b?8_cKNq zA1>m+Vw(MWtIXmk&XDG`Z)E-7CX$u=;tP>0cmyPAqrnUvgiEwd3ujOO-YS+k7=9A_ z(QKBkNz4*>3Cul0lPqC}4oE|;OeD11ZHE^KOYnY?Y2mTUfiY<7EW^yjJHU>gGsGML z20oPESw~Z!-noIMwN=qHp23*K(L8XdF<|JBE5(j8GV67jat33Y6EFY;Oj^gUD`mMu znhcgqYpG%{DHGX(kAycm0fLFdi~*x@al$5Dkpr2g_74!k;1FQnG*ohT9I#cRfI`kYgA+r@ErOoH`<}2mO8cL%kP2R6f}F z=c{Qn1A*C!eiHye5f{r@77Dxkm&!l>UqBF>1dy|m7^FY{jI+2+Qj=g3C_wU6mQ}Z0 zfl;fLZ3U2;9AP+$MfjiBj%XJI1cnYk&>aOJoa%~Pok)S#6&Z`34<Q~Z>*4kJhFk?pSHTes)KExFAX%>0;XSih)gU@Ukn$RU z#E~}u*&am^cXCCt1dt{jkd-1?$g*OzIs}6VsX-T4`dILiw|@?by-GiCG#b&IOzGG| zvF%&9@LVf(h~7RCKx&oe1!Er;z_?=q<3>8i$F5nWt1fSm^n)A#Ij2%ypM7)5d(Rvi zR$D+Ld4>Xvkz6suKXgFQ+Q2%-!l&CPl?O4GWebLkfrS@1GsOT#d#pDX!3?C#gg-qk)lW2LsJe0CGIRH39KlJ53g(017@BR^7zZ zxkC5h!V1OJ@cKdqq{PG!1qcReVoN2>U|E^VJ_60p?A#~yhz<&>cFcTqeK%-rcopa5 zdjN*#pgRn9Wp{o~$?Qi+6lO3xA|F+VUt#qS-QLjJjeIACiKOD^Q=!<^CmXU7TJCDJ}YfyGQ2$}sc+Zk&J7ozMtrB#QBbzIvT{7~aTAUifW-fA7 z!|b?gXNNNwSg^ubkq2QHDIolNw+|lbI!@Mn4O(1#?F`9&02>gRzRZ zh>aP*fHA2Zdnt_r?GOM35SBjMEkJ-(XtkpVRA5wU+kw<32Y3g}Jd~v>tE`coz7#P$O zSSv^7qz6EVO5` z{0=Ulp^u6bD9jQ&D5WA@UciPnLcA zkL<}3sbY4pR4I1ksJ**psWQM=O8%FUB?1_fehtXLl8F@lsE{IfrVitb3xnkd%1Y6D z_z9ST#Vf3nz*ita7;vy=mL9F^X(lHDSPeub1y+D%V4TBVta@Flaz(0wyOSz27@QqS zhIrf!PEWy5!)kIl^~}?l(hVq@$s_Ypz*LI2Aiw}U@I62SBgV=8D-$cQnSp;lOgyZP znejjeBijTo@)S!cGnhN+=J`5Kcdb^6Z7tI|HK|{Wyto*)?Jg z{2U$uX@XCTY+NDUq_+7eAi^1RB~uK>U0tR!r2>aPsBFp%#1cu<(c#4c)c|+6JU7o$ zjXa*E7^JZK%cW3*>0&Td7FKL;tst80p%4BD9{i6Qilx{bR$nNi`F45`f*e-YNy7pZ8_LcV9v z>Ui+$3gmeacs{c%oYU!W1~yD0SAL%vh`~5V_@k3oI0L}|pw$lF@H@STJgTO;4@Zk@loQ+jucsMj`_RG&W}R1|237`G8)W;xImK-i1{-d4lRY^D@pXc+ zH3@4r*c>ODuK9b23e)QQ-P?&D?;KL??2x@!B3OawP)`V7@cOxAySYLwZfB zy`fjue%e_CMY&^3xtzlW5=Xog?pk~-+R(xs)0)ZQq!85Rt z55NIbyayx@vR-mu-4!V8X|Wro!WaEw%WIao0_${;cc3bn#$m@tYD`5Usxj11qf#_ zj>o;5Ou@Vv6cl~~izX;As%I#vI;5SNx{@NbklcI*_sptSXGXA@+`WvQXRe&_P$Vh2Kd3?RJOH$1Bt3}%Ms>M8O!@VD?9{7xK) zmL8i)s)QX329|c+iyb_}k@A8iD9~gkv(aJ}d#;)yCM>NDW(0Oh`khe#0Tf}&3B?va z4x5}4T*v@K(+7Fu90u}(?9m1*AZNl123){^Z=gkAlVeB~BDAf5ythTU7a+2f`a_!d zhuT~>&&Ys0$|uo>MdM|U6y(NZ?M0VQfKVP`F0%1Srgsfy@>Rdaq7|Yx*rT9A(Og zCbbjOz5Ih`IBw1Aa8Q)x$aX~SocG!uB{CxtRub83gM&4G{RRiYa?{IPM=*pP1uTDV z)^L>Vr#ut&!=ifCF2~{E1po!b6}`8$6VfQhD4bbg3iyZH$(4R!)HvUMQ#;>& zLG2Aj`vdX?w)E!TmCfM|xjlk`Q^jb0x*Z^)`uW5 zD4QrZO6~~^2^_EZCClCFj~FrzjOwR&YfLvDxSXQ8xM-!DZanZ$FElRUTYn0OcH41$ zbsIq76%GSar%pA=jl*tfH?GlI?U1crlPetKZpi&hK=ihW-`Pa>00pOA^_$?EL2z_!`Y{l=jcZ@LM#ok4+AQnKBB1&%}h@i%T zEf9^-XiU=(dyVCqdy^YAigcu?U~l;~^UX2W-uvuxK%?(zZVqR!?_1xYoVM3kV~jcH zT5As)WHqZ<&1zP&n$@gkHLF?8YF4wF)vRVUt69xzRel3kfuBext&9Sm(na?{#z}yt$@%&n)4MP{1|$tkizbkSfKp%61A8@S_&w*K8HdY zaupz22S~v;vMf;k$`<&q6%_n?7WZrlzLi744LOdWFjK5i`U{)wN;(Dowu*wTtr9i_ z-^zAi3IOprw7>$TzZSH9Hboy!qp?@=X~L~C8sAt(<66onrm2)hUN5AGb3EG*E+&uS ziEllCwhPM%ED8Mg3JUtqN(#E3B}~yl3GFB%pZ)Q!4~Xyn`4n(8iTsWx|GzFK@{44e zSzk%dAsa_jw##W0_;ZGUB20m&Gy;%9@;kiPwE^+oJCDNeua?<`3kvHj zl3DjI?=kUo4lRCML&?uSr{ssbDXFK1lJ3{glKY?1qI(!CqSNU>{{Z+(#=P z?w7}m2VYQX@8`6%=QCP-e;38y-A1#!Hq*3@4F)JN49ck1H8i4SHAS|qrl|X66n-nO z&*%GoznB1u|B0m(aCVsn$_nun$xB-D1tgaR!>f7*g>@A>fPtBYiwot8^V|~q+KZd< z+geI_$v`~ZBOv5FK0pPJzoz0R-%{z*?~Pvai}znLZQ z6ZR694t+uI(Dp(Nj64Y=5xE3iSCNeELTbMkx1e_?Eq$_wmiO)vCgeXpM5~{EN9E6c zpvvb*X~T{Di#(-`!;a0mVa_P3+(c z!VC-gHB-9p*9-ex+`^}|l=z^QQdoi@M>&rU3MG*jo|83LDlMK!=Dt~%JKul+eTXb(H&Fb1D@&!K`sj(!2Su(7-h{Br-Xjlic_+}3I zA6`Pn_X?vs?w=&Xt4>VyrOdC&pC_E%@6?|602==dG~+r*%)dtS$E`Bp#$ zQ)aMyO}Mj;SyHCF1hUnvSQ5sdgtZn@D6`o2yG7(x6DQ%VNZ5~wB3;6g-&Ver_x(M~ z5In;WSsCo$$OX5L$zx-NnIoFo`tr2l8E*o^0OSwlDFAXUzXw9%g)D{BIyXod z40Bh26dDZCqe1;Ui*$WHm%U_>L|h_U?18QcNN15f+(oF%Q56y`VFyPq9-F39)P+?v z>E3!8&t{83!Xp5|z@@W)6mkd)bB1^5My|7C*Bbz_v*fG*2`|Ze^cBli4bALQ<~~aE z5wm0o7)V^T+7)C<44y+_$d-*Wc*vP+0@6`vH+1$7kt@zi{EjA(&%p&0baW|=>slxI z!I<`P>By=fS;)9EIsbsvU@$Suw>inx+W~S;WDcQlAt#lP!CCB6U?P0vb%2P(Y6+~* z0cOd*`I47_-N@WsuYSb|mJwlT*)76c7&$Hsx*T<*fW~%KP)vK7grdl#$KR>o8N5km zG9+d-1ETwf0mxfOmRYu{Uos$^NFrfO>DeuT19FlWCqP0P^X*{Ns{}TLLv34Wvdhx@pD94tukd-u*x?}tI~p`*Fc@Hmo;OKO!qFB0!K$L`0m3ZM86t+x z7X?FvF+#3Ff6AbkjIjwBX&!G7^6*qK(dgj!$VLqsbEvzsFh3XvgMeE^zE8lF{@B&DSN7-ER^a|aGa=R?2%g7 z8!CY0^#$X%mGTH6z!E&VY}rH@!eK8iPz?Q?@()mdL}Rf?mH^VaMh0h$1_(@DMOk}A zW)Swm15l^hs@1O?y`=wa9cGT#K=J@=dhcEdr%{$4-_B81yB1|NF(3_j;uj%UM~6&t zt|4IjXQjbzFvRbNMArqxlfzoDL<({+^fM_^Cko(;8mTb@U^oL}&O?x4!$;OV`%%@g zUi1ZJ$7@R`s?Z2_R#Q?>EvAZ`LE zPV%J}7NxkzUIXCtsxMxT5)9-D{)CVh@~CI(;vd2e?qG*A7+7QHgcj`f*f7oY*VAoR z(&WNWpz}GDK!K;0(a1afGh`eCf*Cx!d$Y(E7MrqpcB5*GnGU94pj8R}q$GXj4psoP zN`Bs&r-ucMRS&)tcA#vc%!NCpk02Fb$uLePaYie^Iw$OrmJ1CiFH_9kk4-atY zdPrtH2E6piVP?%?VGepJ|6IaMLLdNEL8g{*BDm=8PR>2H(3Cst<^Az_SP#Kwhj4=( z*@_)ltASMgOZf)aE$iwG2sUdB8fXp181z$`=(i&vDlr@*^{fghHp1NFcpx#mQHqCr zVURKFa~>X)yds|gLI+T}{5wF)sY~h^(4bs2f(#>|i4g!A3YN4d_y(gTc%|GArvhCz1y?AYs4fiiVF6 zP)bdpD3**hfdZyr;c6xiFo2oUy;Z0BW_50+=^YzsGQW15CQ~{XN~#JC zsS3GaGIGN=G^qj@oXmnHzF#E_Y(Q)$Q)F|2fYRd36b+O%RgMQJ*jpvQbYMkMfddAh zlpd@73?@wzAgUBA_&pHbicGOY0t~ZMg*r=>84Q*w>|WG2%Xw5z8Q6e$?U*Gci(&Qo z6xk0bF-}Z@2LPB!JlHUNfMf2m;>iC85M$fcQcP=^0D@(x|`)tG9y@>}h5Q|CifL6o zp^RGxLa{L(S<5l>C`t$7gdGUKx+Svi?>6kv zn@9!*h-WO!6*CyXU?2gG0K|hk?6%hHRmaYC={NI)U5-6R-XoOdFyva60Ynf=A^iaX zMjT6$(ue?Yg!}i4BEXpuIuOhTtO{az0M!K9*ISq9o=4Xt%;W(RP%wC4%`chShU}Gp+Jp6< zf6)Lisr{5@d-Ppm=VLbx%M(&Wuq@yw1S<{HDI5@87Ow*sHUb z`iYtxfLLq-B0=_DVMP$TVSM(_=ilA@V5iq-b7YW3-!Gehc|(_h*Zbu(qY&6{_>9&3RjCV$>E(68%f9YH{eL(i=Hjhu9Of=BFA z(qsU^iJw<3Kkk}MLo24x(5k7j>)n?_Up(KEF6>O<0XBTVJotJC2&b3I#t8!m2UaX` zH0^^54D8W$U`34r!?QY;1{aT~A*B<^WAhA_F16zwaya0YZr`Q(N|X~X1BC%KdxC&; zN&}%kASAKtCxSAAv3ITlqgG=Ef6ma#sq}Gn3=J+Er`WM$mOS5|-wX1HeOfMmvw;6g z8=N6c>p0F9vi2LbYNig>T4e$UJHh9-U-UQ%`(NaA7?(`5dh(%%ux!Aiphi> zmv|0d5AXx8sB?w5#|gfRdwIvjG?6I`s1F-1_RwOGhLla@pJz$ZCIINBeca?1b^T=9 zT9PM#z{n3SFxWSA-4yzG)oA)Cih5unO3hxWKlFGsFS!yHpEjPL~6Qlx1 z0kB<2He~Z)LgPKR%#gvt4E{K8te7r5!0$++Izx_RkGr1+4A|le|EN=SDIC}YQ&6J$ zN7_gk(7`!Mp3sMsP7rW(F!b%BV5FQUysq6+qcxvwS2NrP5V@C#wg(td76ueL?)7OL zd2E^?g9gKuLF63aA1P7B;9xL)_QeYm0HDvFc{F78MEWQ(^0fm9b|AckECMWm4+a^B za`Yq6x3rtibQY2C0XNCsy;$4z8`8+J>3?Pr?#d%a061}jc4N@NA^~RY6kfc7Gg2meWf&)d3k41!1bV8H}#`n91;xk5;_D zvc}-T@yd&^GKhO+u`DTO*uju{FY?cB1Bk=zH{?8fmQie!1EK&0=lrC!G55U>3}jK( z)p64@+)2(125wr`Ug&V9e&7QFFq-pBx8Tq=Jp+`B8YoB9!qJe`@4v?6#jKOh)b5F; zAB)yIwVQ^0m@FALi5ukhmKs}eSa7K zx+DtkEfvYa`^(*nFj?Bvr4a=h(Q`rAp=YX-q<*Za=}q>5Z;E+%G^?P|KJ z@M^af7e?c;Ljebd1YTR^`hZ}cmCQuVJLDo;3+yveW@Z0+j_0DBKFDexFv8-@TR+Pu z#XRghWb@YLLrIAO471YT-S*l3?Ew2aL7mUwhztct{}V|TAXc-QTeklNaWPk$?#ok4+AQnKBB1&%}h@i%T zEf9^-XiU=(dyVCqdy^YAigcu?U~l;~^UX2W-uvuxK%?(zZVqR!?_1xYoVM3kV~jcH zT5As)WHqZ<&1zP&n$@gkHLF?8YF4wF)vRVUt69xzRel3kfuBext&9Sm(na?{#z}yt$@%&n)4MP{1|$tkizbkSfKp%61A8@S_&w*K8HdY zaupz22S~v;vMf;k$`<&q6%_n?7WZrlzLi744LOdWFjK5i`U{)wN;(Dowu*wTtr9i_ z-^zAi3IOprw7>$TzZSH9Hboy!qp?@=X~L~C8sAt(<66onrm2)hUN5AGb3EG*E+&uS ziEllCwhPM%ED8Mg3JUtqN(#E3B}~yl3GFB%pZ)Q!4~Xyn`4n(8iTsWx|GzFK@{44e zSzk%dAsa_jw##W0_;ZGUB20m&Gy;%9@;kiPwE^+oJCDNeua?<`3kvHj zl3DjI?=kUo4lRCML&?uSr{ssbDXFK1lJ3{glKY?1qI(!CqSNU>{{Z+(#=P z?w7}m2VYQX@8`6%=QCP-e;38y-A1#!Hq*3@4F)JN49ck1H8i4SHAS|qrl|X66n-nO z&*%GoznB1u|B0m(aCVsn$_nun$xB-D1tgaR!>f7*g>@A>fPtBYiwot8^V|~q+KZd< z+geI_$v`~ZBOv5FK0pPJzoz0R-%{z*?~Pvai}znLZQ z6ZR694t+uI(Dp(Nj64Y=5xE3iSCNeELTbMkx1e_?Eq$_wmiO)vCgeXpM5~{EN9E6c zpvvb*X~T{Di#(-`!;a0mVa_P3+(c z!VC-gHB-9p*9-ex+`^}|l=z^QQdoi@M>&rU3MG*jo|83LDlMK!=Dt~%JKul+eTXb(H&Fb1D@&!K`sj(!2Su(7-h{Br-Xjlic_+}3I zA6`Pn_X?vs?w=&Xt4>VyrOdC&pC_E%@6?|602==dG~+r*%)dtS$E`Bp#$ zQ)aMyO}Mj;SyHCF1hUnvSQ5sdgtZn@D6`o2yG7(x6DQ%VNZ5~wB3;6g-&Ver_x(M~ z5In;WSsCo$$OX5L$zx-NnIoFo`tr2l8E*o^0OSwlDFAXUzXw9%g)D{BIyXod z40Bh26dDZCqe1;Ui*$WHm%U_>L|h_U?18QcNN15f+(oF%Q56y`VFyPq9-F39)P+?v z>E3!8&t{83!Xp5|z@@W)6mkd)bB1^5My|7C*Bbz_v*fG*2`|Ze^cBli4bALQ<~~aE z5wm0o7)V^T+7)C<44y+_$d-*Wc*vP+0@6`vH+1$7kt@zi{EjA(&%p&0baW|=>slxI z!I<`P>By=fS;)9EIsbsvU@$Suw>inx+W~S;WDcQlAt#lP!CCB6U?P0vb%2P(Y6+~* z0cOd*`I47_-N@WsuYSb|mJwlT*)76c7&$Hsx*T<*fW~%KP)vK7grdl#$KR>o8N5km zG9+d-1ETwf0mxfOmRYu{Uos$^NFrfO>DeuT19FlWCqP0P^X*{Ns{}TLLv34Wvdhx@pD94tukd-u*x?}tI~p`*Fc@Hmo;OKO!qFB0!K$L`0m3ZM86t+x z7X?FvF+#3Ff6AbkjIjwBX&!G7^6*qK(dgj!$VLqsbEvzsFh3XvgMeE^zE8lF{@B&DSN7-ER^a|aGa=R?2%g7 z8!CY0^#$X%mGTH6z!E&VY}rH@!eK8iPz?Q?@()mdL}Rf?mH^VaMh0h$1_(@DMOk}A zW)Swm15l^hs@1O?y`=wa9cGT#K=J@=dhcEdr%{$4-_B81yB1|NF(3_j;uj%UM~6&t zt|4IjXQjbzFvRbNMArqxlfzoDL<({+^fM_^Cko(;8mTb@U^oL}&O?x4!$;OV`%%@g zUi1ZJ$7@R`s?Z2_R#Q?>EvAZ`LE zPV%J}7NxkzUIXCtsxMxT5)9-D{)CVh@~CI(;vd2e?qG*A7+7QHgcj`f*f7oY*VAoR z(&WNWpz}GDK!K;0(a1afGh`eCf*Cx!d$Y(E7MrqpcB5*GnGU94pj8R}q$GXj4psoP zN`Bs&r-ucMRS&)tcA#vc%!NCpk02Fb$uLePaYie^Iw$OrmJ1CiFH_9kk4-atY zdPrtH2E6piVP?%?VGepJ|6IaMLLdNEL8g{*BDm=8PR>2H(3Cst<^Az_SP#Kwhj4=( z*@_)ltASMgOZf)aE$iwG2sUdB8fXp181z$`=(i&vDlr@*^{fghHp1NFcpx#mQHqCr zVURKFa~>X)yds|gLI+T}{5wF)sY~h^(4bs2f(#>|i4g!A3YN4d_y(gTc%|GArvhCz1y?AYs4fiiVF6 zP)bdpD3**hfdZyr;c6xiFo2oUy;Z0BW_50+=^YzsGQW15CQ~{XN~#JC zsS3GaGIGN=G^qj@oXmnHzF#E_Y(Q)$Q)F|2fYRd36b+O%RgMQJ*jpvQbYMkMfddAh zlpd@73?@wzAgUBA_&pHbicGOY0t~ZMg*r=>84Q*w>|WG2%Xw5z8Q6e$?U*Gci(&Qo z6xk0bF-}Z@2LPB!JlHUNfMf2m;>iC85M$fcQcP=^0D@(x|`)tG9y@>}h5Q|CifL6o zp^RGxLa{L(S<5l>C`t$7gdGUKx+Svi?>6kv zn@9!*h-WO!6*CyXU?2gG0K|hk?6%hHRmaYC={NI)U5-6R-XoOdFyva60Ynf=A^iaX zMjT6$(ue?Yg!}i4BEXpuIuOhTtO{az0M!K9*ISq9o=4Xt%;W(RP%wC4%`chShU}Gp+Jp6< zf6)Lisr{5@d-Ppm=VLbx%M(&Wuq@yw1S<{HDI5@87Ow*sHUb z`iYtxfLLq-B0=_DVMP$TVSM(_=ilA@V5iq-b7YW3-!Gehc|(_h*Zbu(qY&6{_>9&3RjCV$>E(68%f9YH{eL(i=Hjhu9Of=BFA z(qsU^iJw<3Kkk}MLo24x(5k7j>)n?_Up(KEF6>O<0XBTVJotJC2&b3I#t8!m2UaX` zH0^^54D8W$U`34r!?QY;1{aT~A*B<^WAhA_F16zwaya0YZr`Q(N|X~X1BC%KdxC&; zN&}%kASAKtCxSAAv3ITlqgG=Ef6ma#sq}Gn3=J+Er`WM$mOS5|-wX1HeOfMmvw;6g z8=N6c>p0F9vi2LbYNig>T4e$UJHh9-U-UQ%`(NaA7?(`5dh(%%ux!Aiphi> zmv|0d5AXx8sB?w5#|gfRdwIvjG?6I`s1F-1_RwOGhLla@pJz$ZCIINBeca?1b^T=9 zT9PM#z{n3SFxWSA-4yzG)oA)Cih5unO3hxWKlFGsFS!yHpEjPL~6Qlx1 z0kB<2He~Z)LgPKR%#gvt4E{K8te7r5!0$++Izx_RkGr1+4A|le|EN=SDIC}YQ&6J$ zN7_gk(7`!Mp3sMsP7rW(F!b%BV5FQUysq6+qcxvwS2NrP5V@C#wg(td76ueL?)7OL zd2E^?g9gKuLF63aA1P7B;9xL)_QeYm0HDvFc{F78MEWQ(^0fm9b|AckECMWm4+a^B za`Yq6x3rtibQY2C0XNCsy;$4z8`8+J>3?Pr?#d%a061}jc4N@NA^~RY6kfc7Gg2meWf&)d3k41!1bV8H}#`n91;xk5;_D zvc}-T@yd&^GKhO+u`DTO*uju{FY?cB1Bk=zH{?8fmQie!1EK&0=lrC!G55U>3}jK( z)p64@+)2(125wr`Ug&V9e&7QFFq-pBx8Tq=Jp+`B8YoB9!qJe`@4v?6#jKOh)b5F; zAB)yIwVQ^0m@FALi5ukhmKs}eSa7K zx+DtkEfvYa`^(*nFj?Bvr4a=h(Q`rAp=YX-q<*Za=}q>5Z;E+%G^?P|KJ z@M^af7e?c;Ljebd1YTR^`hZ}cmCQuVJLDo;3+yveW@Z0+j_0DBKFDexFv8-@TR+Pu z#XRghWb@YLLrIAO471YT-S*l3?Ew2aL7mUwhztct{}V|TAXc-QTeklNaWPk$?Ca6lnqjDk_SoC>HD$>4J##-c(c& z5Nm9S(ZpyhNmP>fMWZpvjWLQ!Q@YsuU$gFd*FI>p2{=kEDr=_{7S6V#R`Vd*U<-^K*j2L&HwAQ;)a>azH8&R=GU z|KXK1_If@|>RV5d{Z%xzuZpJiR?&=}O*E@#3(e`Rp?Q6^w6MRPmOR`}%bxDy*i8$& zYH4a?_TQRFOMi*|d)6YDneEbGcpX}5&kh}orfekz906C>y!Ar{HYU^f-g27QS3%(& zGEZxlLoiVNp3RZvc-FzotWYXy0*GU9iPILMJ{ZGcz zxZW}f>nf$NwqlytUP_Yy#@$Mq&R|4$Zlbwe)eJ9sV)r2r8KqL@PTgUh&c)v zR~d|7*HXYQYY86X_~DSsedo6 zeef~mJUUDTPmWUYlVeo+^fCI3|PvO1GMVtM-;YypeOi# z9j^enoufc8vZPggb=~ahTBiDNEgCymqJ$L;M8HpL$e#i8zhDEzt3HN8IU5VTQ%GZ4 z0Y(vpwHH%3vm=7p0WfBFZ4p+)Gb7R&h`h(2$;7XJc8aQ=e?^;Ld`(+kd_&b7__~R| z-|*}-l|B2CfjLUqk3OX}4-Qh|{k@d%@&H9$EU=qk?~j-8#OKN4QJ^^bNP+7D62zGl zJ{(qBU=xFJjllpjE-N7X&Zm&yw@LB=J?rLCXkRIXv=vZDYXOaEQ-J8~n0j};FauyD z^zWfeo>;H}lZ}br`tmH*y=qz%tc32^xg;5wGE)huuE@R{d( zX~v}@yGa%{-^h|heLZ+`wY)xJC@05rV%j<&!0-WvEG z&)2;=N7XOSFndl@`O_0r@c5`m*J}2Zcm{SQ%ieO%#-?4!w@$M79J3pXNLXS7q@#d* zzlwKJK={pD*>N>PGAdyPvjSS}b7GZ97hV_4OhQWv`CkMC1UJOe9tuiVR{FG{(oeORQdmy%FIYsU>sjbNHImy*eruv41lyLKpJ}DH1rJ znK!?CD=mE7KtbCUllSoz@_q#rX0{zm*b}k1Trb1Y(nqW?VFxn-p5c2YfqcGzbe+`Moleg(;kb1PM!QnO1Ono(lrP`8wV_%u(3E-}|v=_?(KP zQJ*arfFzC7h6H5hO~9ydtixTv(Az{@@1C0R;&HsQVNFNvJU(Im_~k$i2{W8;bpS&0<}WX5fojr z;2)Tv=&ns{ybYA`;1eo;c0vsLp8`^+$yNntTe(~)CNt|6_0|g@$mFm9@HMhyJxy#b z7Qe%LMRo|L>nw3ehK#%>vIu6N00k(Bh>i*xd!40;nT*x~zCoNEFi{&5*{l_WKX_ovH5zD9!~ z2s=;!NUlg00GYrAVWd`_FXc%~XAdc155a_@3g7-(2j$P$p_{r5kO~Ke*Z?V)x<^1^ zrc7upA%DmgGA=fEyl2!*F55csIT0%i0V_rwTPfKUnu=I$Vw46@&}Ip~ol6#$tud_y zS`AVuU0u`)$g)snqn5zLHoP_#gy)@vjU5eWrD$!GP5k@iZ0b4eA^4k%*+U!wu|`KZ z1zt=OFM+wE+wf=G1^@XhVGoh)>T}Mnj>ob=W~jKTRl)!Th6#gbP%O;~5IxJ9(NQIZ zTY}aysbJZXD*aWXopd>?)Q#-es<8vTFEA}r%d!^s*Z`RWfN!!?RP;pK?~M zI|BoZLb?ogRA~LIwd_f8{kym@tQAwY1BB&L2V~5(T=L;!7TK1uGwrftSZ0LuuHYX+ zea=`U44_Dx{sseblL5JvOQ9|KsRdZ=}IpP!NykIBZQZxd;GWb#3f1~NW(isysrL_1&Z8qNJI7>#vFg#M z5@47yb=EkiTJO)l;p$w0QS#)tWLMZxM5h=2F}r(0kMMpCVd}%u5FaMVE~woK`YREVuG#Y>V;{OptXiq`RKt`gT*={e!Z~3t4(l zbz3*5o~z9%*_h(T3W!tknj&UKp6rDjqU8R4B7yKG^sZ2y!><$|HV*+q$K5WJwEcs% z;qG-Unb*EW^1(!l(IWyVoUsJ_qNFSE_e^0)u*Q;5jU`BbCo@Z?-`z;FJGao1o^7(R zgyvu-Pj2p`&jc8(eoTD1#0hzf=ioVLCIUeC1~RMId%Glao6}V-{sF)R5C>BSL($|! zyJv_y4%xEhsvV6+dr&yXzq(Gbp`=dj$-Div5-7POxL6wQXWdd%+GY25bWiao6E>a4`)4 z#UNdQQkyVKZa}tdUNS+GE=(L&G>mvLPby>wJBXNQTvdWeU-RH&*=t83iSJ?F_&HdG z-9h}`yzZ?cf#_jPWw}!RQ89oW<2y=e^mnQ53&_xdsj8LouM{gN0hcsCfpq<*d5K6D zgTgEs(^6o&45+8zG5U9e?E?+#kkw@W4+03~RF@9{il&A zD0kGgSu?e3vj7Y{0aApC*JB9>(&Yu+b;1gG24pHq2crYtp|UG`sbVl%ifC+SF?rU; zxHlkZ!z29_P|l}Fv1J8CONAj_K?do9!2=Zi8m;j5GBNr{%~#M~f#CxjFd(LDD|^IN zd5q_<8weoujVJ+wL7j4^!cMBJV6aSv@YK0HOnfojC`lj5dPOr2C1I zFJwJPhaoFAVAgXMwn4y|!Qjj^1V8{I1PFeO?ini0RYndV5RfT&)))rE!ixdY>GpsO zE1YWGTSt!wRlHTgz!uF@1QeF9plh0Z0TlKWRPn+Vo;YM+6L=C)SwqTDL}KM5jdhGj ziOK;PmCg$Mt#SN!!3+y$dZ>w9_Hv)U-QU9Q;psSOIywU5|3iv0driWmM!A|PY_aHU z0WdsqW10&TIIQ=OnenZ~(lVFUM_U<#R3>IE(XPJYIaJ~R5+J~vgcba^LT=_!FoO~J z+d64@4lkZIH~>MBh)o`B={g0*PR5umoPh;0FhN{A2IJ-*cngCQax+&ZG4vLL!!Z^K zz-|lTLv7eqccfaIgs`JCXY4 z*Iy0omI$yyfZ)H0j=}J<>4Osx?7pEb@BPUV@;^c z&IL8eGTCnnycVhUrBoW0HQ5A2nvR*1$%{eo+{3`=;2429vP^l*7Y2VZq{{+KW0GA< z#tM)z0G2WSm11q*jQVVa35GsA>gSSYLkxL-w2(Y^FOaXeiANX%Df`60mZK}=Rt8}U z`-{k!v5o;SI%{-*>>|YwO7g%yuln zk;WDQWywHqF|tLkVOYw<{Egs9B-=s*%AY|Q#Xx)1#|Rto`e8X!25E-1Axcbj6jmp* zVPws0X;mQQ^lX@?*zzV&jyM5DOdm3qpaG+@GGUD#jS3`xNE*M!bH{udQ8iN*0RA3+ zhSvX}17qa+D7kbLSrOz0a)cWxM{b%$Xg&_jjo`=83KW0=U(x03kiC342PNJf6hxyc zFwsZzhCDIw2#;+s@;7}?$BUQ96)>)R>+?SuICw@~8J{j%F4z6CWO%TTjHrsHVZ{sz zXFS6SBFUq6u3`ub9(9Ucy`mZY@mO1xZzo@D_#$6P{CvDHVOY^r`Y>aXuu&wEK?kVn za?x~Qh<=~?pa4VeuV~Mgs}$A6*lT3MFe%8auwq9rJFt3(Nk1j%8?-c z=abzV6n~y5i{b1O>-~q=*5#j}x8;3siD4I zES5$xqa0uVU(YN=g!)ZA-um)Fg*j@NmKv0Rl zumA12Yk|7a)OrMy!+T(c!srJD5T4s()IEioX*vzu3*MCd-X;W@oH~dzdjLDEivlN+ za*FQ%lN)bZp&AxLZ+i5~vkC42ipZ39 zP}$qV{xx8f&pX~)wM(~K^QRdN>{SchM8`7uMcjP=gRHasU7T07*qoM6N<$g0jPq+W-In literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb14.png b/examples/moving-saw-platformer/assets/Climb14.png new file mode 100644 index 0000000000000000000000000000000000000000..a05065828f9087a851955ff36180b36cbcf8b9bf GIT binary patch literal 5078 zcmV;{6DjP8P)Ca6lnqjDk_SoC>HD$>4J##-c(c& z5Nm9S(ZpyhNmP>fMWZpvjWLQ!Q@YsuU$gFd*FI>p2{=kEDr=_{7S6V#R`Vd*U<-^K*j2L&HwAQ;)a>azH8&R=GU z|KXK1_If@|>RV5d{Z%xzuZpJiR?&=}O*E@#3(e`Rp?Q6^w6MRPmOR`}%bxDy*i8$& zYH4a?_TQRFOMi*|d)6YDneEbGcpX}5&kh}orfekz906C>y!Ar{HYU^f-g27QS3%(& zGEZxlLoiVNp3RZvc-FzotWYXy0*GU9iPILMJ{ZGcz zxZW}f>nf$NwqlytUP_Yy#@$Mq&R|4$Zlbwe)eJ9sV)r2r8KqL@PTgUh&c)v zR~d|7*HXYQYY86X_~DSsedo6 zeef~mJUUDTPmWUYlVeo+^fCI3|PvO1GMVtM-;YypeOi# z9j^enoufc8vZPggb=~ahTBiDNEgCymqJ$L;M8HpL$e#i8zhDEzt3HN8IU5VTQ%GZ4 z0Y(vpwHH%3vm=7p0WfBFZ4p+)Gb7R&h`h(2$;7XJc8aQ=e?^;Ld`(+kd_&b7__~R| z-|*}-l|B2CfjLUqk3OX}4-Qh|{k@d%@&H9$EU=qk?~j-8#OKN4QJ^^bNP+7D62zGl zJ{(qBU=xFJjllpjE-N7X&Zm&yw@LB=J?rLCXkRIXv=vZDYXOaEQ-J8~n0j};FauyD z^zWfeo>;H}lZ}br`tmH*y=qz%tc32^xg;5wGE)huuE@R{d( zX~v}@yGa%{-^h|heLZ+`wY)xJC@05rV%j<&!0-WvEG z&)2;=N7XOSFndl@`O_0r@c5`m*J}2Zcm{SQ%ieO%#-?4!w@$M79J3pXNLXS7q@#d* zzlwKJK={pD*>N>PGAdyPvjSS}b7GZ97hV_4OhQWv`CkMC1UJOe9tuiVR{FG{(oeORQdmy%FIYsU>sjbNHImy*eruv41lyLKpJ}DH1rJ znK!?CD=mE7KtbCUllSoz@_q#rX0{zm*b}k1Trb1Y(nqW?VFxn-p5c2YfqcGzbe+`Moleg(;kb1PM!QnO1Ono(lrP`8wV_%u(3E-}|v=_?(KP zQJ*arfFzC7h6H5hO~9ydtixTv(Az{@@1C0R;&HsQVNFNvJU(Im_~k$i2{W8;bpS&0<}WX5fojr z;2)Tv=&ns{ybYA`;1eo;c0vsLp8`^+$yNntTe(~)CNt|6_0|g@$mFm9@HMhyJxy#b z7Qe%LMRo|L>nw3ehK#%>vIu6N00k(Bh>i*xd!40;nT*x~zCoNEFi{&5*{l_WKX_ovH5zD9!~ z2s=;!NUlg00GYrAVWd`_FXc%~XAdc155a_@3g7-(2j$P$p_{r5kO~Ke*Z?V)x<^1^ zrc7upA%DmgGA=fEyl2!*F55csIT0%i0V_rwTPfKUnu=I$Vw46@&}Ip~ol6#$tud_y zS`AVuU0u`)$g)snqn5zLHoP_#gy)@vjU5eWrD$!GP5k@iZ0b4eA^4k%*+U!wu|`KZ z1zt=OFM+wE+wf=G1^@XhVGoh)>T}Mnj>ob=W~jKTRl)!Th6#gbP%O;~5IxJ9(NQIZ zTY}aysbJZXD*aWXopd>?)Q#-es<8vTFEA}r%d!^s*Z`RWfN!!?RP;pK?~M zI|BoZLb?ogRA~LIwd_f8{kym@tQAwY1BB&L2V~5(T=L;!7TK1uGwrftSZ0LuuHYX+ zea=`U44_Dx{sseblL5JvOQ9|KsRdZ=}IpP!NykIBZQZxd;GWb#3f1~NW(isysrL_1&Z8qNJI7>#vFg#M z5@47yb=EkiTJO)l;p$w0QS#)tWLMZxM5h=2F}r(0kMMpCVd}%u5FaMVE~woK`YREVuG#Y>V;{OptXiq`RKt`gT*={e!Z~3t4(l zbz3*5o~z9%*_h(T3W!tknj&UKp6rDjqU8R4B7yKG^sZ2y!><$|HV*+q$K5WJwEcs% z;qG-Unb*EW^1(!l(IWyVoUsJ_qNFSE_e^0)u*Q;5jU`BbCo@Z?-`z;FJGao1o^7(R zgyvu-Pj2p`&jc8(eoTD1#0hzf=ioVLCIUeC1~RMId%Glao6}V-{sF)R5C>BSL($|! zyJv_y4%xEhsvV6+dr&yXzq(Gbp`=dj$-Div5-7POxL6wQXWdd%+GY25bWiao6E>a4`)4 z#UNdQQkyVKZa}tdUNS+GE=(L&G>mvLPby>wJBXNQTvdWeU-RH&*=t83iSJ?F_&HdG z-9h}`yzZ?cf#_jPWw}!RQ89oW<2y=e^mnQ53&_xdsj8LouM{gN0hcsCfpq<*d5K6D zgTgEs(^6o&45+8zG5U9e?E?+#kkw@W4+03~RF@9{il&A zD0kGgSu?e3vj7Y{0aApC*JB9>(&Yu+b;1gG24pHq2crYtp|UG`sbVl%ifC+SF?rU; zxHlkZ!z29_P|l}Fv1J8CONAj_K?do9!2=Zi8m;j5GBNr{%~#M~f#CxjFd(LDD|^IN zd5q_<8weoujVJ+wL7j4^!cMBJV6aSv@YK0HOnfojC`lj5dPOr2C1I zFJwJPhaoFAVAgXMwn4y|!Qjj^1V8{I1PFeO?ini0RYndV5RfT&)))rE!ixdY>GpsO zE1YWGTSt!wRlHTgz!uF@1QeF9plh0Z0TlKWRPn+Vo;YM+6L=C)SwqTDL}KM5jdhGj ziOK;PmCg$Mt#SN!!3+y$dZ>w9_Hv)U-QU9Q;psSOIywU5|3iv0driWmM!A|PY_aHU z0WdsqW10&TIIQ=OnenZ~(lVFUM_U<#R3>IE(XPJYIaJ~R5+J~vgcba^LT=_!FoO~J z+d64@4lkZIH~>MBh)o`B={g0*PR5umoPh;0FhN{A2IJ-*cngCQax+&ZG4vLL!!Z^K zz-|lTLv7eqccfaIgs`JCXY4 z*Iy0omI$yyfZ)H0j=}J<>4Osx?7pEb@BPUV@;^c z&IL8eGTCnnycVhUrBoW0HQ5A2nvR*1$%{eo+{3`=;2429vP^l*7Y2VZq{{+KW0GA< z#tM)z0G2WSm11q*jQVVa35GsA>gSSYLkxL-w2(Y^FOaXeiANX%Df`60mZK}=Rt8}U z`-{k!v5o;SI%{-*>>|YwO7g%yuln zk;WDQWywHqF|tLkVOYw<{Egs9B-=s*%AY|Q#Xx)1#|Rto`e8X!25E-1Axcbj6jmp* zVPws0X;mQQ^lX@?*zzV&jyM5DOdm3qpaG+@GGUD#jS3`xNE*M!bH{udQ8iN*0RA3+ zhSvX}17qa+D7kbLSrOz0a)cWxM{b%$Xg&_jjo`=83KW0=U(x03kiC342PNJf6hxyc zFwsZzhCDIw2#;+s@;7}?$BUQ96)>)R>+?SuICw@~8J{j%F4z6CWO%TTjHrsHVZ{sz zXFS6SBFUq6u3`ub9(9Ucy`mZY@mO1xZzo@D_#$6P{CvDHVOY^r`Y>aXuu&wEK?kVn za?x~Qh<=~?pa4VeuV~Mgs}$A6*lT3MFe%8auwq9rJFt3(Nk1j%8?-c z=abzV6n~y5i{b1O>-~q=*5#j}x8;3siD4I zES5$xqa0uVU(YN=g!)ZA-um)Fg*j@NmKv0Rl zumA12Yk|7a)OrMy!+T(c!srJD5T4s()IEioX*vzu3*MCd-X;W@oH~dzdjLDEivlN+ za*FQ%lN)bZp&AxLZ+i5~vkC42ipZ39 zP}$qV{xx8f&pX~)wM(~K^QRdN>{SchM8`7uMcjP=gRHasU7T07*qoM6N<$g0jPq+W-In literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb15.png b/examples/moving-saw-platformer/assets/Climb15.png new file mode 100644 index 0000000000000000000000000000000000000000..f85b26721f5e5afc93389c7bcea65673340f5792 GIT binary patch literal 5168 zcmV-06wm94P)k7RCwC$T?boK*B12`yr&|<(93|>5D?VFLIf4Dq9`CDy%)s> zqG0bamT2rTYBc8QGqJ=(MFl|w5qtkN`|Y*Qy)$ zlVdk#NML=ISWtbo3CQOh0l#G^X6RttVlbF7f!8xB@b^U&z-G?UXB^@)8Vt+;80<>` zRKS&m0*X0HpK$~?=WAf(*ul8Eko+&DlmEpu3b>s9L4f#ennEGR=hLuD*%VPk69ipo%88ucG*lH8kbPTAKP|gIHWkHANl&-x%m~ zEQ!1i&Lr={GkXWfh^EAEu+I=Mep$dEq>%5~dE|R4nS6gt?(&Pe<;9To*9;o=u$+ds zl~Z_gDMdCh3z`?xsC!H3iHvjF$fU5EGr65%S*A_7|(#h|9D*2va zFn*XrKF4O0&+(-9zNG)jc{HS>jE1z7&=6+E@Vg~60$?;%Fc_8eWy>;(ZLJa@07BBk zjWqAk7D|1*jnW_QpoLF%Qu>n}ayyM5o6o;Xezuj8-fp9q)46{-sor}MDVRSu782O4 z2PD?^BJ$ik$$3HXIXYV+tiV5*9hVo1OaTm^6LZM>$Sgv#=zYj81#Y>~6mqwK!dicmnklh)5L33rT_!4G^#$GV8qA`Qcdt2qG#taKE4C z3p4Pz*SFKjYj+}f@oL0#J?mm=PdVGdm)i$^{Ha)a14`EJquK z0eR2%Q0a^BXz|O#wDi?cTK@VNt$2OhW_S$0133B5_tK&#UsDP*X3mq%H2d`y8n$!p zdz0&PaF&Vy*|3l#SJGL6Xt6QZc>(b~olJpDduXrtjZ<@l834nwYbtqeokU*zGvLAk z3TY{%kj8upZOCVK6xi4i!BQ2|yhOlAc(8_&A8n>AW&|d=^3@Sq`TBcW_2vhvd3%yp zv#oi1N`BV7IZ0KoPY6hhUmg;+DGUkr(#|3!A>?8M?OY1Na6b( zWe9!_@*2RQIr1bWU7BpQr#F0a)5J_PI!HjZV?O?@fW`GXF+INmt_fCNVrc}RSmb^MfN~73!e8u5yQpZM-n@XNk z$P`xp+P4704u;WmVCoFgwVZ*3)Isv*KibM5ujRj8Em0e6e0vp*X;>^1J#c-TEEs%l zk*=#5cG+rB(Ux-p^21#5AHMt(A+E3kQpFKhP-Bi=mkkU7Ado9WR%1B%o5Yfm!V?Im z40d3Gb(!i43?nE;=~65?Oa;%s<=kXDO>bW(xy)#O56B|kYwVM13fVTD`euX+qkT9c zM3^hS1hQrDBNq05&KLG_2niilay3noD#(`T@vUrav#K*71rl9FX>tXfhwfu_!ynXk zAyt2cC3r2uVB{$o9R4Dk2SWe`q%pdAF~zi0QgmY(S!!a*vTvFsuBa%Wx&Y^{`w=9K zmanIfQ~D5uyFN!|+vExo5U7>lji49-8P0%Uf*>W+Sz0om?vi|BmB`hfgVC*Qv2!ou zXbZu?oQ_SBU;>cH=5jGCg6P&t3cIj~Ja;e1hJcv&)=IN2d0Zd z#~1V5!C!Dcv*Sh<1>R6uuq0i#>@2YX!VW#=-eSo;AT5}{C9iZqPXG6Su;i6-w3YpI zw?tZS>Z3J45YZv$iM&@%5zS@fvwsG8fhFuqu&5;3!smtGyPGSO2j{D0RenK!=TgLf zAm>0X5(q$$0UJSKmIU9%0U#j)2qdf2CRvFO>cod&WmmBuScBZ-oeoORfB+0*KC(afQU7h z((uL-mROc8mR%%@2u@VjjPfD=7t)-QA;`)Bh~y*ygSFQVN~T(M^(yMJGE2f5ILc~L zQ5N<*Fllp8GI_d396Q2SBzs2b>MB!LzQfKAgv@w-Ap;A>&FmDIEN`Ctd+D(~4|m4`e;9#YMKR5}8} z?9>4XI-4puuckYcUul*|8LOd@9P_EdeE9g1{a+3k!?0pbR77B}y zkZ8`-$F;1W1ePsqGUc%Lqe!TOVk|D!zO@5^k_iA)%urw;D1hu`a)6NBv4s-aYdMNr zsfE225@87-jXEG@WWBhM0WmmsUO+*&vz&h`*K7Awj`SNB*SCtJ6ASsSGjL@fvn?i4ueg@7d}zhkR*f$R|O7GF@-#pV=pjb(ga2Lg=3a{)&B<9_>c_;xN5F6!kD+dr%RU29 z6@bKk3KC5O3J9s;&`~zg0SPxmTF8Y$84v^{@PBT_F}@9(7=im4x3Rb0T|f-0JvZW zt5)2G)#MEkI}I*+B6>ZEI9e`Eh{O$wMHaNda*bxmOd;7NH^R^xC|f?+G;6|pATjr*&NM(Bf1B6peYY6 zNS3;|-rE7$FC#*-TWtCWD3C8*x_+@sSCB{-19DSETww-KM%*ovNmRXA%VmP&T33k- zfi(a~H{1s!@O$Jk@EPdmLT&@8>dJSBR5cdUV1CcAmZIL@j_R*HUCU#}Htk6oLAX&K8vAjXotnmoIjz zB43g)<}xt(5`7KkRScbnyo75~7AdSzJAbnK2LQC&cs$AmgxzO|L@~gS#IV~16k4Av zJ`7a@&kZhcWmn&MLxmYWM`o$MUL!CLY++C|wgmkKN3Ylt!V?z4&K@#`Tm}9Gs~R#h zw1EL?C|0G9#!>+Z{vks9X{=QN1d%5O0{#N52w_$Pqu6;x)z|vC%D~<_O7hr6^nMQ* zO~!QJg1)F<(IyOARk2!KNC^JGF{VYe70gv-3zhcHk>?-U78Hp6{>T%7i8 z4G8`lR@Bls!jqyWx@7pXxC|iuGDeU$gMfmg-faCIFsF@-Nwou`F-D|}!4ZHUX$A|q zo}-LG3%!}EtX?y|EkL3~17HCJSb=>S{Q@EmD*ER~xz+_g(qzqvqS&|7rM*;L6vMzA zH3HKGV<2VlF_0Gc83D*>nU42)!X;{h$?r7d*9j1pwF`)lq_ROi`?%Wp=iI^Mg&yB; zrph*`>?krg0t{Gln87)!t{r)wF`Dz&!9i2>CAIMts9C_DTDoEcfIwo3IvW}p`0>7J z;jVc(+`!cn6d*ejq?tf&@6nh8IXkEWGfQL4T$}TE$YJyn4D6!O7HF2%z2P6jdoXz(o_|ig4)W;I zVEkjoAnAga%MxH))#V9BV9+TqQJL;zx(b(n)clNIBRe%1^4J_t9vkDylYa^@U<|WIq)hiQdQ^7U5g7E}+A@C)99`CgLAw29Fzt5& zB(tM$@=(_W1XmwnLct36s&O=+d^8QLnIM3m5!+)^yz~GIFks8huGlie9+9Cb+6c@k z4ICYy9t_gumKW*5V5}G?juev#X&SgDme7^bKX0U5CMJNuHpX>givg5<-LS<07y~$` zI)NlW&6A(Vf!vpjaZNznile2~2ZdRStzsyJmX{?$s zarp6FJNs@yF|g&t9AzgpAo#XryYgKFSI5fV#B(j*B)S$TK1XIsgPDGsgX|pgszsKL zNDGtWUiqakq+fO<^<5Y)w*eL|j6r@N;jo^s7#+RAr`SL_p5y?EG<&me8nEOGaw}t> zRXtwrOGhO?2c0i21&9ax3OUi?mOAeQyMuDwA!=HC)rCCbPnLZt6V|^Vn*B-?^)HOJ zO%#5Ii)7GiD~vD}C>aFrBZ#`@C=dV!KW5pLNbWrO@KOD8BBhN-BD-}Hg>9;ldY%B{ za(RdxRiPb1Bgbq&x^Sw)Q4JJkf=As~9C?iw$r@16v$F-0@ceRv)!y#^6ex!!iXH>Yez0XSGY7aan|RWfabZbe$ZeW;}o40>inB+8J6n=8sn? zfI)@#W4|vPxgMnnGjQGG8FeA2bl)4!GJ&kRmLIvBXFu*wGja6S)pa5Whd;&pBFaL! zA9)J=7Nk--?>nFN)0|IUI}%(66iAbPdP7&Il;ZZMcwZbvizo^;EPYo{e3}6a{pwoF zJ{QVKq^a6?LTM*MXzX77X|7DtH>0H6{)XcTKQ=&IMY7yieupru8z^M;hIaZFw!)ew%fnmG4_4=o2!9gNwJFK9G_eb%wR|6u<_$y!- zWb2cJ-5fATKykb0_t%d=hphEFFmMT*E%*3~Cg+Ik`1l9A;HV{u^8V^)VR=QEjuK1n zVaJ1_9_0ZOB$I^OIF1!3%dw8*#DtIiS#UjLPXR@j#*7N-D3(1Mrw0QiijYSo;;8kr zZ-aT&;eHUy0w!G|pI=l?;B$&I^;5~8?8}SqX!t-t?r8tX!POGR&ytk(B%NSRqxu&b zV$4*vi1O8aS1UYz7C>4Hltk)`ZBh~m)=E7K6=k7RCwC$T?boK*B12`yr&|<(93|>5D?VFLIf4Dq9`CDy%)s> zqG0bamT2rTYBc8QGqJ=(MFl|w5qtkN`|Y*Qy)$ zlVdk#NML=ISWtbo3CQOh0l#G^X6RttVlbF7f!8xB@b^U&z-G?UXB^@)8Vt+;80<>` zRKS&m0*X0HpK$~?=WAf(*ul8Eko+&DlmEpu3b>s9L4f#ennEGR=hLuD*%VPk69ipo%88ucG*lH8kbPTAKP|gIHWkHANl&-x%m~ zEQ!1i&Lr={GkXWfh^EAEu+I=Mep$dEq>%5~dE|R4nS6gt?(&Pe<;9To*9;o=u$+ds zl~Z_gDMdCh3z`?xsC!H3iHvjF$fU5EGr65%S*A_7|(#h|9D*2va zFn*XrKF4O0&+(-9zNG)jc{HS>jE1z7&=6+E@Vg~60$?;%Fc_8eWy>;(ZLJa@07BBk zjWqAk7D|1*jnW_QpoLF%Qu>n}ayyM5o6o;Xezuj8-fp9q)46{-sor}MDVRSu782O4 z2PD?^BJ$ik$$3HXIXYV+tiV5*9hVo1OaTm^6LZM>$Sgv#=zYj81#Y>~6mqwK!dicmnklh)5L33rT_!4G^#$GV8qA`Qcdt2qG#taKE4C z3p4Pz*SFKjYj+}f@oL0#J?mm=PdVGdm)i$^{Ha)a14`EJquK z0eR2%Q0a^BXz|O#wDi?cTK@VNt$2OhW_S$0133B5_tK&#UsDP*X3mq%H2d`y8n$!p zdz0&PaF&Vy*|3l#SJGL6Xt6QZc>(b~olJpDduXrtjZ<@l834nwYbtqeokU*zGvLAk z3TY{%kj8upZOCVK6xi4i!BQ2|yhOlAc(8_&A8n>AW&|d=^3@Sq`TBcW_2vhvd3%yp zv#oi1N`BV7IZ0KoPY6hhUmg;+DGUkr(#|3!A>?8M?OY1Na6b( zWe9!_@*2RQIr1bWU7BpQr#F0a)5J_PI!HjZV?O?@fW`GXF+INmt_fCNVrc}RSmb^MfN~73!e8u5yQpZM-n@XNk z$P`xp+P4704u;WmVCoFgwVZ*3)Isv*KibM5ujRj8Em0e6e0vp*X;>^1J#c-TEEs%l zk*=#5cG+rB(Ux-p^21#5AHMt(A+E3kQpFKhP-Bi=mkkU7Ado9WR%1B%o5Yfm!V?Im z40d3Gb(!i43?nE;=~65?Oa;%s<=kXDO>bW(xy)#O56B|kYwVM13fVTD`euX+qkT9c zM3^hS1hQrDBNq05&KLG_2niilay3noD#(`T@vUrav#K*71rl9FX>tXfhwfu_!ynXk zAyt2cC3r2uVB{$o9R4Dk2SWe`q%pdAF~zi0QgmY(S!!a*vTvFsuBa%Wx&Y^{`w=9K zmanIfQ~D5uyFN!|+vExo5U7>lji49-8P0%Uf*>W+Sz0om?vi|BmB`hfgVC*Qv2!ou zXbZu?oQ_SBU;>cH=5jGCg6P&t3cIj~Ja;e1hJcv&)=IN2d0Zd z#~1V5!C!Dcv*Sh<1>R6uuq0i#>@2YX!VW#=-eSo;AT5}{C9iZqPXG6Su;i6-w3YpI zw?tZS>Z3J45YZv$iM&@%5zS@fvwsG8fhFuqu&5;3!smtGyPGSO2j{D0RenK!=TgLf zAm>0X5(q$$0UJSKmIU9%0U#j)2qdf2CRvFO>cod&WmmBuScBZ-oeoORfB+0*KC(afQU7h z((uL-mROc8mR%%@2u@VjjPfD=7t)-QA;`)Bh~y*ygSFQVN~T(M^(yMJGE2f5ILc~L zQ5N<*Fllp8GI_d396Q2SBzs2b>MB!LzQfKAgv@w-Ap;A>&FmDIEN`Ctd+D(~4|m4`e;9#YMKR5}8} z?9>4XI-4puuckYcUul*|8LOd@9P_EdeE9g1{a+3k!?0pbR77B}y zkZ8`-$F;1W1ePsqGUc%Lqe!TOVk|D!zO@5^k_iA)%urw;D1hu`a)6NBv4s-aYdMNr zsfE225@87-jXEG@WWBhM0WmmsUO+*&vz&h`*K7Awj`SNB*SCtJ6ASsSGjL@fvn?i4ueg@7d}zhkR*f$R|O7GF@-#pV=pjb(ga2Lg=3a{)&B<9_>c_;xN5F6!kD+dr%RU29 z6@bKk3KC5O3J9s;&`~zg0SPxmTF8Y$84v^{@PBT_F}@9(7=im4x3Rb0T|f-0JvZW zt5)2G)#MEkI}I*+B6>ZEI9e`Eh{O$wMHaNda*bxmOd;7NH^R^xC|f?+G;6|pATjr*&NM(Bf1B6peYY6 zNS3;|-rE7$FC#*-TWtCWD3C8*x_+@sSCB{-19DSETww-KM%*ovNmRXA%VmP&T33k- zfi(a~H{1s!@O$Jk@EPdmLT&@8>dJSBR5cdUV1CcAmZIL@j_R*HUCU#}Htk6oLAX&K8vAjXotnmoIjz zB43g)<}xt(5`7KkRScbnyo75~7AdSzJAbnK2LQC&cs$AmgxzO|L@~gS#IV~16k4Av zJ`7a@&kZhcWmn&MLxmYWM`o$MUL!CLY++C|wgmkKN3Ylt!V?z4&K@#`Tm}9Gs~R#h zw1EL?C|0G9#!>+Z{vks9X{=QN1d%5O0{#N52w_$Pqu6;x)z|vC%D~<_O7hr6^nMQ* zO~!QJg1)F<(IyOARk2!KNC^JGF{VYe70gv-3zhcHk>?-U78Hp6{>T%7i8 z4G8`lR@Bls!jqyWx@7pXxC|iuGDeU$gMfmg-faCIFsF@-Nwou`F-D|}!4ZHUX$A|q zo}-LG3%!}EtX?y|EkL3~17HCJSb=>S{Q@EmD*ER~xz+_g(qzqvqS&|7rM*;L6vMzA zH3HKGV<2VlF_0Gc83D*>nU42)!X;{h$?r7d*9j1pwF`)lq_ROi`?%Wp=iI^Mg&yB; zrph*`>?krg0t{Gln87)!t{r)wF`Dz&!9i2>CAIMts9C_DTDoEcfIwo3IvW}p`0>7J z;jVc(+`!cn6d*ejq?tf&@6nh8IXkEWGfQL4T$}TE$YJyn4D6!O7HF2%z2P6jdoXz(o_|ig4)W;I zVEkjoAnAga%MxH))#V9BV9+TqQJL;zx(b(n)clNIBRe%1^4J_t9vkDylYa^@U<|WIq)hiQdQ^7U5g7E}+A@C)99`CgLAw29Fzt5& zB(tM$@=(_W1XmwnLct36s&O=+d^8QLnIM3m5!+)^yz~GIFks8huGlie9+9Cb+6c@k z4ICYy9t_gumKW*5V5}G?juev#X&SgDme7^bKX0U5CMJNuHpX>givg5<-LS<07y~$` zI)NlW&6A(Vf!vpjaZNznile2~2ZdRStzsyJmX{?$s zarp6FJNs@yF|g&t9AzgpAo#XryYgKFSI5fV#B(j*B)S$TK1XIsgPDGsgX|pgszsKL zNDGtWUiqakq+fO<^<5Y)w*eL|j6r@N;jo^s7#+RAr`SL_p5y?EG<&me8nEOGaw}t> zRXtwrOGhO?2c0i21&9ax3OUi?mOAeQyMuDwA!=HC)rCCbPnLZt6V|^Vn*B-?^)HOJ zO%#5Ii)7GiD~vD}C>aFrBZ#`@C=dV!KW5pLNbWrO@KOD8BBhN-BD-}Hg>9;ldY%B{ za(RdxRiPb1Bgbq&x^Sw)Q4JJkf=As~9C?iw$r@16v$F-0@ceRv)!y#^6ex!!iXH>Yez0XSGY7aan|RWfabZbe$ZeW;}o40>inB+8J6n=8sn? zfI)@#W4|vPxgMnnGjQGG8FeA2bl)4!GJ&kRmLIvBXFu*wGja6S)pa5Whd;&pBFaL! zA9)J=7Nk--?>nFN)0|IUI}%(66iAbPdP7&Il;ZZMcwZbvizo^;EPYo{e3}6a{pwoF zJ{QVKq^a6?LTM*MXzX77X|7DtH>0H6{)XcTKQ=&IMY7yieupru8z^M;hIaZFw!)ew%fnmG4_4=o2!9gNwJFK9G_eb%wR|6u<_$y!- zWb2cJ-5fATKykb0_t%d=hphEFFmMT*E%*3~Cg+Ik`1l9A;HV{u^8V^)VR=QEjuK1n zVaJ1_9_0ZOB$I^OIF1!3%dw8*#DtIiS#UjLPXR@j#*7N-D3(1Mrw0QiijYSo;;8kr zZ-aT&;eHUy0w!G|pI=l?;B$&I^;5~8?8}SqX!t-t?r8tX!POGR&ytk(B%NSRqxu&b zV$4*vi1O8aS1UYz7C>4Hltk)`ZBh~m)=E7K6=(G_gjFy-Xa(F~&Gi5d;xXielHlX3zfiIrqN%0MRu=%sk$^Yn=sB9&mnlf8XBw zoOA8h&vm&j*X6ogm+Nv}uFG|~F4yI{T$k%|U9QV@xh~h`x*X;5{$VBsTwg@~R~L}y z_NnBWkv|K>ffx#H%A(N6nG{@?LBX}@6vFQZ{<_o!<}@yA`W^aZbw28K~%g`q$M{>J0i z6bi0(0r|2(8nZYG0AsmChQPR;LV>rIQs6H9n>NrCa!HB(>c^5+Rhc4bBfdxk^?L-4=0 zko)Yc8e<&Fg5=lTw=UbR$h~E2o%_3W|GONi&{T(1bgM6jmPVg3|>EGAyLH zhz^!2|9>nJ7=D-Mli$U8ID zY0nQ(_RGVx>h*CddUKMB-<+nBw?EN39_x9OygkhyKgFLv!JrOP218rQku#saH~HmG zifgavabn$8k7W>LCy_s?aCo84YXGhbCwVD^M=Cs*ntr08hv@b7Ph655}AcR;E}Jzhf-S*8#fn9MAm z*fno{q|$e11;Xa{7io)(OL|`!?J~OwiO3XjLwSr<_ zZzKP1ph&I6*&uEtfDtIw%T*OQG%s|rYy$<;xqxGbYWhCLKW7yJa@3!pIf zISd3D+SDf-C0m=?Rz^_|R@+T5A{kyMbrRo9@IdKM>nMS2dF*h&1va0Pv*ixMA12Yk zF#Op^3>Y>bO15C=U)SeKnv1LoH3m{zcmPZrQe?m|Kv;(rijuAi;xjP#T+X~wJN8SO zjOakdHleA6$2y9BQAS~VW|Ot$9hVdt@)yfM#xsb~ zoG>717~8a#qB=I16YRNbx_F&HVW|zcuA>C9#f7f;2uHrd0r@Itr2HYiXOqM`(Ax^q zD~Ixj)pQ1uZOYZ8=Jhm(t8QpNd;p%%Q*_uvxg_8uO0<`(VRO&qdIgzUJcCALeEWE{ zz{lG$EhQBBvoh-e#Zlyabe5#%zUPu9A;FD>2C3;Ik5)RSj|6bKD|g$;*{bV{+`ih9 z+gm&YhCYn5tI-T(GV421)J#rui&=8YEZ*^HAeU`GSmq4b%31AJTVNU zQ2|MARS|;8R6s6%5=ey|kP9MNr3Mf-_GJR3QZhJ5BYqw_0tS?!wRtkh?v+z{!ehnv zM7B6nM0RKb;Rr#I>wv{!BKe(3mT;HK*9t{TSEvBVlnPx*ma5L-At>lpb1?{W#vNbr z;nP``Ay-B{Vw0>R-2ho7zGXsbE~KCf3&_1ZnmqT+P_o4nkGjNW?CG-b7I@16yU6&1 z&@z!$#O-A^C}v9{UA0eY?L7o(X+q0ZnZN=r>|o52_I@y+T<&IE>Lgbx%R-L}rk-Vb z2uqd)2w)7=V_4%V3jbxf0>asr_xCfEk8tXa3f|1LSZ0GAamS3;!8pmTaCga&9#N_p zB~r076aX=@ENDBjAgptsg`WN5ut*NPprtSVT1!e%q&!XO#sAd!bbAcQp`QNBNv`Fxm2~nx@v!xww*@CK?Lb5y5vkLLgfV z#fXq0k5nCkw#jrZ43pW|S9E;GQF2@+)(T}yClFgKRl1ltOI67m6&-mmkJ56MKdD1n zHVbe&AoclbFcka_-Us5ygMasr0zrhZbU9x8qRQdtRHZ0YhA>n<1p3L~;PRn$xg{wp{Yu>7eWPfwxj*wNN^!Mx@+kgS?}nB;-Du zWOX`)*Jje!F!p*STbMMoPm;JENqM$k`cY^Uu6cb@d;!sd_B#L=10RFm035y!FtS+k z&<{f!2G#%MCmU#7Q*jp{W`sP>Cx4bA&)sb5oU&uhMob+Z!oGp#B9aw{T^GURV?9K+ z{TPwLkb-oSgh-U6)4&>*t%uomYaxh|I4n%HR0?}9tL3GS`QZD{6rg5!EV`mRBfCOHgPo7A7ktLp=O99swsl~S2ePDfF zt%od>C0yB$1y2#_QeG0Gqa^eJ%T{fcLc_mA&&yDE+j9k zXhN=Zba)?4>?3RI*VRrF1!a*5MI^uyC83CtS|dvIA{9#)3?A)r$W0O#i&#%z%3xBT zACNi){jLl>00F=N0`MSHh>ZA_E%F)@8rR8^Fyv|k!!Qa%69`8qI?e!sDjmOf=Up)l zf63Z{Ui6W6_H~<|1pR9D63(_bO2RoxA|y(bbRip3yG=IAU7o0So6K+9$#8ay9AWbD zc5(Y2`4~Qjs6fqu@0r@XNu+8V!$ou$ay8r<9qb`UDsV#tUSG^W5^2D?@qKR#k@SN& zOF`-=P_AhxTDpR;V5OxCQ4;omYm$d*ZN$0_2$2F$nJ#;=wnzpxyQNYhAW09rk4hXx zCB6op0gzT0DmuE#6;>)E9_CQ^!%Xt!g0^2@y}UT5H#Wy9C>H554L;Q(T^ZWob2JoV zJCNF&g&G20Fzv}Eis1>z3SgWbcpo1FG=M-85ntaKhSki67*fSi2@k{Guzr2{>R&WY zqzckyLNWZrNQDjQ`kkW$P(->iMLxdPd$fkt7tjbTVdL2BA!BHzBN~JMjflYK z0b&e8L^}piHsX<%ssKy920LHFm3|`0FJaoh7CrZyk>;J$fU6Qs)gfGHmUCeK^tDS zj`Hv`z#v+#+IvcnQJ?%<%NIilWBD4$6E=vWMK;mZ<Z#e!S|iyM3;NT6xqk?b7~GLILT6QnKEXHmcW}!CHo4#qm3SS zF2EpSc=Ez)vS@HE2Fn@yOeBvX4>@`m(y%%O$sBqCYM5?~04C%KQYaEty^=!juHc`Q zCdq~Wl?BeTG28E~+6p9ldQZ-g{9Yo)0An%yK=u~t9dYp(Y{(cQ25{~(7!01wa2|sm zWXc%KpdxCrDFUEsa|D)*S~VhS705vhbs%SQhzh)JFeen!W4p7A+)5@m4-n72G30$L zLHa{ji9=fgTZI&uQG4)2Rcpd)}* z4M1QSfL}M@rrxQ@lG)GME@P9mY$7-^%Le90E0|Z@6W@<2r zJ%ceCme&*@V+g1oh5)`=c`)4y=6JjDSU0^~?E z&WP}&;ckaSxtB$g+xiLQv27~hi4Pu?Q#F|B5oNHNGGO&s^4K!j9!k}8TeJWQXJk0aV0w#LT-t+? zUfFpI9COUG0|j|=I?s@OOR`l)JqbvTMst<}xxi#Xl03Ffp#f{7sDIvQax0yvfM9I5 zK-v2-D3)k3+c7pU0_R-U=<&soy1u;D(NlLd_Z+CnFz*dcCgxfJQD)=ve}egZkcgn8|clez>3KcHZY-9-ImQKU>Jj!~lzhKa=F zd!Nu57r*Z#bxN{q>h?XA#Gv^#cgL^{PN4pUW5}&IN+M5ov$OvoLUAg}>40G3t>+2t zp`=Lj5QYmGa^F1pvnS|p%ZHN}QfCI`!x00R{qs4x@_6#sF@*fl^i}q^)V~1#9#1Gn zksu&_1~|wm_7yu{Bk|x&+2v;fvC5a;bOvAPUli4Alk?TmVbq^xZ@`*yDy?QY1Te^) zoEenUP>aRaJoh=_(}Hl)$PS2c;L~_0Cd28?ZJB>f9Y#2g?Y3c}hA~}y2kS2|_W->U zADg_fZ0vMEjP>$~R``V^28fJ9#<8@yoJ^=TJANnZ(M4MBbU@tL8*tFR zTOfLbKFN{ns<(b7Y8WqghQPo{+PSKccvBzTysyqT;`eeoAkb}jZf_4jdix;0M8*+y ztQnb{JdxpsdZ3KmBQkJs^ZR%wT0=jbWUEDb8V}W@k9w^J+7zw2!hmtb@^}pELu6{z z&vcq)+y41uD6}=_(=ZI#YR)D+G^|&CHmAGNX1}5zAahGUKt@ZI^+v#3=jdfsulTr` zcPCr&aQ>8Dn;cn5L}c7jyGg84)%ix~`$k?8^?6cdJUXv2Q!*d-t-aS@k|SvPlvZb{ zvbzyjw)*^fI$9cbZ4*->GQ{BVIlM)0%lr83KV&kn)yR0Fb{DDY28z^69MxEv>{Bqj zzKbQZ_CN$+@(~4ih9UpKNI%gO{G)%50Y&50Q+tdjMtqKR>fhHPpY-$5%2% zFjBO@(Qo=wx&)6_nok}2TrV>s29n#)b^QTAYSaI#A(3)7%>|`5FF6bUxtX4>g+d-@ zng0Qe*RB{BkX}tL&Lnl8To`^~BpCYt#=>q$UuWAE^hJwPE)c`o^Xw*Gq5%Ge=LzG{ pwJrc(_QE2TKaMyb`~P0D{SR$4%k2t+Jfr{s002ovPDHLkV1mOerOp5V literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb3.png b/examples/moving-saw-platformer/assets/Climb3.png new file mode 100644 index 0000000000000000000000000000000000000000..f85b26721f5e5afc93389c7bcea65673340f5792 GIT binary patch literal 5168 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb6.png b/examples/moving-saw-platformer/assets/Climb6.png new file mode 100644 index 0000000000000000000000000000000000000000..a05065828f9087a851955ff36180b36cbcf8b9bf GIT binary patch literal 5078 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Climb7.png b/examples/moving-saw-platformer/assets/Climb7.png new file mode 100644 index 0000000000000000000000000000000000000000..852bdad7a59b313e2714aa9d81068a035fe34f44 GIT binary patch literal 5153 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_1.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_1.png new file mode 100644 index 0000000000000000000000000000000000000000..7f75b347638f1b41ca8956bdde984a4a85969619 GIT binary patch literal 7303 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_10.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_10.png new file mode 100644 index 0000000000000000000000000000000000000000..99a46d2f3b23401387f09e73336160db1de1eba7 GIT binary patch literal 8260 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_13.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_13.png new file mode 100644 index 0000000000000000000000000000000000000000..28e98fb2cb1a43c919303e7aa71771d30e3a617e GIT binary patch literal 8702 zcmV!p1FNz`aWnE&$FH?4#lC) ze$ThQwa(eQ-~e#47(O8z1Q`%n$biUz$U+8021FJzATl7bkO7eakqv?jh%974WI$vg z10n+=3mFg@5Lw88$biT~24u*akmG(d^XeP)$KzsLIJ}D0A}a%A5lI zj=Y+(WFN{3l6{U)lsuRIP5%A7^2IhOa6kN!qM zGAAycz-do(;ne&^oU&Mp|GRS1V|(*~(82QC>3c;3HBB`?(HLRY$W`XsqDpK}rrvZa zp7OD4W!4vN71^J;mu5Y4J3r;V5CDH z3Z#TUqvatdY|An}bG<$fo_7{w%++Pzx*txvVwmJMO;M<-%gM|2?NCR2)nfgk+;_&x_1L&dp9DkcN608Z9&3& z+Y$F(9zq%y{@Q#-&^iSzffoOF1u`K21c>CY$seqZH;pTC=$-|qTXW&mH5)G1X2ZQ} z?f{JIOAyqv45M$XMCeTkh!}z}{?2A3-rb6nyW5a@Z+m~F+}noaN86G3bSHwU=04L4 zvrlG!PfnT+Wk6m9A}={)%_!Tc*7ccR+uxo8hikcT?3^WmacwR1*->F9R|-B!{b$?!L;dd*(~~>$$M&$bmy=E}RI6>$N%X=$Z%b?gj9>z8HZ$k~GDX z(FY^>ZXVKTu+tyx#?*)Vko{;sW;}WqGaetH#{-y7-)B91hv4i%8UbU9N%~+XyiR0v zDC(*j^pE~89tbA^qBqlLhwTjl(Uk++t2wamoXM-hnbhG%smil^KBcOK2q1Ngy0IMN zZmy;@#b9ifz@R~9O2~e=A32W?V)o<1nET!l%zN)B=DmLubLjc3$A@@G3>Z@jgThjn ze^Jf@Wn)bd$NkcQNWb*w`@L&>GZ!}32u8<@A619%^+o-@5q@he8TTe6@i2BElVD7z z!Oo>YXAl;?e;kY7KZzwzPGKp<;wLBhZFA{o4A?YM3xmR7#=pM}e&xAOl?>F)UIilm zO9P^v=DN)K=1f?3&VbF;>9FYsG80bM27vT=N3c{KELFwd*}{7Q^9q)dm;&a%cZ?tW zWlv9I<UftQ;6?AB;8nmB!9Z;K_#!rcT!bwYn?Ab8gIV)oKChkyl)hMcV=9>_RY}yH4H$iU z)eCh`(~!aG>g`WiELBZ*TWNEHV6yn&x)}1^AfE8^deS%l8<>$j$- zC#h`yk@NE`u4C52>=nNNSXmny0QSVZY+1p!(6^c*&QaGpREV8=&=*h#UA)UofgGHiTu z7I8bX;65P;A*+)xyLT_qWfY_0z>ZYPFeJ&H`ni7 z>+3nNyfO_|ZCOL046d?RL+H^p2fp3&FzWh3g!U{!?9CNOre<(*?*?Su%R?^p9rGz= zEv1yTno`z=CufjH2ELsI0oqBi>**QHEL;XFZ!u_a`@@{R&uU#qCchigZf!u?ja5jv zzKqK0rSK`8@=Tzns3ld1{96a4uM<|#RS}w(ru~M2U_dNe2cSrROy_|(QkCUOrtU>R z0;o$LOFj}qP*Mm=1~rA#3CbKY_Jw4~OUXx85tQ|hk6_Dt$C3B=D2_ipkEZ{q$BoZh z(fX(osj-33ljC5ZDhC5~c|PZwXDPA4 zSKt(h$Pg&XHhP>zZN{6d5XpgPMA%GYsmZc=Dl9Kg9RkIgRAR%YtsFRY%!C`M#D^k; zz(iBEHGv|FVlJhzrQM6Lic;9xn`^PYcMCS%+l{;j`;m8lKT4lo#2nYK-*pD!jQttWWf+NWdp)m-f9oR2--%dzLidhEWn1;_8~#qU4Aju)Ty;Q7Zb z`2J}vUOcJ9%a3b;uexz;RVo5S9LCuyBho>DMAs3R=%R#a!Rp966N&9tCSyfo8fIR} zKz#MYuSH^2S50M3O~9bYv+L0kC!}VUv*3XwzPUi;)s;2q4S#OgoC%ADDX@G63a=6d zgu;mcc+umit1}QwATnDsv9x6}wp^ZwcbZdivMCwo=rNzRooUO)iH>w=Pdnk4Qded)?boijNU%UM*Xb7p4}`E3GweM(=6oQR-^ zi&8nQWG7D5$COhR4Pzk6*18@RwdpUZ!h%J8h7^i4b+t%T!qS#qI|DKu-t>G7K}u?! zf>|w-u(l}$jir9LU+ji!C4T5A4?FP}V#N1ua=F5R=85M=902l%$N4GPoS;mhhOP1HxRkDgXDbcx+ucHZx>*}HR|!#cApi%e!m*|~ z0SOy@nw^6TrkeU1Ch7VaCusPar3e@LPY@NRrd!la$rP8SWoyRS=ju-P$`)UmkRdLa zIK{kTQl@ZOP?AQJt(}swhU7+=;xOz()I+VNGIf~Oq=O7m0;O@v5I5|krXrP8Ft0HM<)uORYpDTHq=T0i_3@XJ2Ke~A18!gPMN3U2>IvAMGXXd= z7TB!`9HiGC(!q-Zn)qA33!2xP;#{sOPG+m&{4{lZvsWKDAp}ku0tFPO^zf_QW+*NW zz@Exb%&Cb*Y)Ksat5V?7luqi+qO_VVsSMd;C-qLZXTjzs^;E2k=YuN7t{Jdu&3bOM zGrWq*eAB*5{KEzar7JD%bhoW6O;NcB^Xkb`C{qTYNL6A>P#o#NJ=>;X^pz<{xjY#Q z8&c47+6(`Azy_ZlwZ(U5^zo7g@9!t|DRl6#z!|j_V{m$(I}Y#kK<^oE{GSVM_^i+o zUthAo^HM|n?VK(i9ydnUNikZFS)%2z4IUh|!Iyij@RvLjyf|cp7X=3NsE^*G4me&B zj8$c!NIesZ;DT7Vm8HP0W)iHKvRRsKo7UghzBUM!?VZ`6O6-xmhJe5CGHie-=&PFQ z=8imSNe4rc=Al?HrPO5%_=!{{HU!0i&Ol%CkLZqBnA)C$6*K?`Ym!h_5{Bl|QTXJP zHJ+c-$BTSYz$s1q?t}q4OGl!%E)Vg!rz_1b=QZ z#aDF}c-ZKL?iyd*Dj7+s%oSg~Yl*)eWl)6p@`x46%0^*(`8Z@A3&yw;;qbVS0Q=HZ zSkuX5DTTt9>{qk@Vb~B9oh;Aw+;CEel8J`3{-S^aa{^#qo;CobHhpO7Vh2f3Sjihi z{YOOST%@+oL@sUL&^Q4{YolqPgV9yujnDF}@ZzElp66@h52y4=C3dK;4#I`naX3>K zfr9!l)HDX;TGL2;*Wh5l#x3aAhjyHl<-3RX}H} z#-Op>2X`+y;V=0#$R*nNrc8)iWe%vKGyYWlXdGw^$Kj?h6t;xma@$DUYj?t*JB@&Q z^!j^x_^itUJ?*Y&ZSlnAI&ZXBc%rAo75^{a3@FpXHRtn{xDTPuOz3v;Tye17BAd1H7mQ=f+w;)xBFHIbPQZ-3p@_ng` zOy7n~-GQ1jXR5Y5TC?HbnuYL|OiXH;h$Z!L*jF1n1tL7ZqzBY%QAul# zlDd&NOsd${9FA=*;W*M3g36AO=<0UH7ad|Mf62rj>Ecg!4bju-h`M%9R5f{{q1FTK zm9F@*NQ9SFdidjMW3*p%!HMz!tgQ+|dVL}SPesAuP$Vo*$3tA0%B!5cZ$90!f}}m` zM}d$(KG(@`pEZ0uL|4U#^5`M+N&-@x3MvmFE+Z%vX#;*zpV99nR+PSMDI5rpds7Ai z8z&*QJ{38nkj(_-e2ouUs$KAm8FnS5p=K?7Tw#L322bp345Siy4A!)a!|t|GxY+51 zw(Cy#@VYsk-_WIgL2eEYXC0Lpf`6r;InRH;DI*qR2#p&Z-n|TClp-u zM1HF`N}Ju$)aZ<-RTg;JqL0573-QGX0$l8YHRT~luZqPes!*G(@KpAi9{! zpHS?5_p9VJsmrE!7L4DCYF0AUG#plqp=zLb0yR<)6{bj_T$(V{PiiLfDq+TNN#9#j zI=LvfYMQMyED4lE%Bn48pRJZ@%XwK z`HBMy+gxz^iaYXK+)>`*f-9FD@l}fna90m6FALFDVUPV)K2&9eAcazv-&v}%4n)A> zWE{klvP7hE3swR*OHG}cLhJ4vY7%oLjbU5X3!`1(^#TW>W#6^DVFg4^peQij9q}O# zUb+znBE~i}4tBF%I!X5y&kWjm;H)I9ct1ih5^!P)}#` z9V&Zo>fvsq1O=mv7ge|#%doduk^#pYG3Sca7SB*6?(6V@O`fag*u*)qRJZW zaJJ3~$EsZkt_$+X%p05S@%3#|+cQ$z0|V4HIpScm4_4L&BRS8b)6rJNM^}+k5cJ(^ z*HGrv$60Zz{vuA%NS$4$Yxn^fm}wGiMshc0 zIhc%*2a`VlMqETqSIGp}QuF0nk&1w-WJHm7tSq2viMr{sG8g==&VbUC7Vy3nKD}y+ zq82y2+v0;w&4E}#WYp&%N~89u@rkni`re+u(GQ8xGZb;!u?b z8j7uOt6Gfz>N3E~$K){|=;C84kB_zaVBJ~Q4^tAg=XzT!xQTS-jI~tdw3HP&Wd%7- zo(-?ST$_iYY^lSIa50bo@-yR!ll(=?uVz zj?q|fH5@rtV=#kaL+2Qjbi4EB{h#f6__|UPw;Mz_(dvbLEq=%&cn9jJxhyurcNOaR zbCV7_uG-4}QB39pVf z4~RTBaMv)_ZY_ggayS;IN8==5P7t6|R7w&U^K*%?x{wH`f&};$#Ut!eEGCvlU}H%D zD$1O2iP94@@4c7(u(>q|%Uj1Fr!@j;S7MOd5{J~5SWKs;aMR@=oTmPwxXKZyYu&KD z*&iF50lTzUsV%~Q|0bxFR?;(xjp~$&6fkPx-|qj`M%FWyp_i|m@7CK>nj** zsB#*-I^-pD^!tLX%#tX?@J&<5z|;)|Er9{4qcoOvKp6B>pk6 zF&3E(;h5Pt4s+>s^C{*v5V-nr$gB%TMok1VYr>IT6NY)!W3Z5Vn+0{FF}r>YGMgeW zCc|vKoiQgi7AhEPsdHKaWlliqQ0SY5GC0^hj}fkKDiA3YwLnp(DFLB|3C8=QVe)RY z1P*O8I}!);<8iQ}^3w54EIjk62e=S}$cvFkED6U1N?#MJ!l@LEL|knQLhIrYSeFE! zx)gX*_|+vNq&5)|b>k6V7lV|#C_WNvqY+yZi^%FYL{!Bgnj)V1i{#2kq*O-GV+7*s zV-cL^(`IQTZ)T_~XP~LZX^v2q+*4=X@hS`+h@L8$`5O*|J?hQ&sW&+g1LHjrFy0$E z0Ef1T4#mLyXe_Kx#K7TH4BXE~!}mOaDU3l#5k*NXg372jD36C%MIu})li^gA%7<%J z3OuWl;9Hf5!0H49SH~l`YCM7}2lb<{L97 z%^)g{RMk~Eb*VD=Stos2_tj9O7qjZ>%>we8FC`OAC!@U3ucNKn%2HuR;aHvm=kjE@ zmQyc7;YQ(FmIN2t=3FKTm(paoQPb&Ok^uKh@o*=Qq7>V8YOER*a4Jg7Go;Fp<9_^$ ztqOiCfbf@7d`u@9?Fa*T3i!uCU`+N!!EApN#D}6`PGBsL$H4kzENo84!J7QVIzNFo ze@m*$EH9?Of+{o1;#62(N`+Mk!Qmr?hs6VvZnN(D*(KUuoD937B-mF?gy|B$QUUn{ zn_Z&tN{V{>fc%5?Av)7M%8e*(8Ezd1Qj7!+fiW5khCGI)F%hLPG5L%5B$+=|YGUeR z*kuec>thO}y$ppp10;oHQ7jE=K8J?nHCAO4VX}U7hoYL2Cg1c)KnyYOUyMTdsipJ$ zdW`o(!f?wtNo*x3+d?IZ*+q)kBTZw2jK8lUW2Lg$Y3gClCJi*07o?YE3ZzjuI8p}% zfh(B^!;NEa$qN+KahZ!Hiib$=L|%ABIUs)}$;$R|cS!g&z=P__(G3lD|VvTwlj zhx9Omo6EjSGJS9c1L7lj2q^YD+7n&2u=!I8N(#RmAR5uOKa40FPBX#5l+x3;ObtAc zSD+aF7?guCuW2mfC2AQ2hF48roKG6Ks7XK=Sau?4#ydZjpa&^`mZ_jBaJ8^1$B64)OUnmeK1GaEy85>k)-V6$_l)OGDgA}t>suos-vC^1N zUD14(Z%U1%#8cuW>Fd-WAPfe9Fe7C!Xbh~u+R^-enL-HW@3oShgqpE-oMs$BNp$1~ zR*44rtp>v0@T(zk6mt5D0*cug%QuB=peZdG?TX-2iQ%>|-bebu&{=IvKV!;Zzr&mQ z$w8`MgU?dZSxJgwM$aIyGMYgUE(?Oenh<{9Y#$o9kOg z1AWzCO>npV(x4Wq*s2KPUk%oVK!2e>^yc{TK|h1xhB5s9Ob^HLsf^t=He5ftP{6L% zl3ITdZibw|N#ZSR7Q3Q>IzPBWg0?A{X-Tg3hQ2{S*v*?E5h&u+$6D&rnf_nw3}qFz9Umjl8~gi~L(n>0l-)BDzHf@K^{kodX_7}o_mz~-FYA~g+G{U6+LrkecfB{mq$h*_1SlkIhgfiPG% zny<>3Co!0;{o8b0)DlCNT9=H-UhX0OGw$PC(#CCWCVP{QWC|PK; z+-pH+>bLxADjFm<+l0;8;=!=X8U@m>TH0-kC6_pg+2AuJsD)VY6AaiYC5;Fh@*{#Y z+LF_s@87}qEmTRd(wK+Ae!nzL0)r`oEimnw$vml*8S>!w_Adv!dq{1KQ7vN=rr5`-qn5;qB$$r8nsrAelnUXldct{!fas3=t9mBH@P32bzEII006 z37i0tyus?=r%V-mX-w&Fh%%%w_}PRvbD4?`DpB>smZSYUV}yf{V}*i%j&<11IvLV` z&>JSBZe^3n*nC)i(dS?=Y~nSUE}LE|S+bD9jQ?{2sjg&3FvKi9X!50|Y9NEba=0m{ zHcG5-v@85;RvfT2$HOR*%q)C$*?{$pnXE(4WN`nj3K<-9;wk8>a_l7Po8&QkQkIn@ zx3a-h^)I%8(;>f|A6 zW5_=i`mf{D9QhDG3zETLlc3qG^jBu1llp$GHp*O+P7aB}ey#`*vpLQE{nzj^by5hO zF{(6Z&#b#={NtryeULg>HI(s3`aKgqA2W4OzoAV2p%G=v8#-_51jJ}-Xd$2KSej$= zgPSv7zeIp3S|=c|)f2lK~4?j5<4{ zIcFcNY$8z|E2GIVD=JKBg{IrB2!|l?}j8h0(uGuQ~Hufk`IXxBvhF zq)9|URGq$z*8TW#A^?Ad0m)W%Hjmh7Az) zv6e2zdn3zi{-;3L;8Cj6p5mUt&NSA`FlA8h!FTJ_k$3!5Z|XPr_U!Lf1I+A{%vsm2 z^RvdV0ir$GZ6;MeUos#pWw9=u4IrzwSQ*L`z<i7RNanuAcwf|dlOu7P#6_vwEGj4OAO)>A+7r2+Qpgr6 zUw4{UOxj_%aqMcNT@mX{PsDH0UlOoP(NJCTDbxz`oV+qsF6;yKsSDPOwF{xw?;_}X zjdq6bH#-@>kD%{0FH75FdMaU`(e|)?qH{?*>2Kv3zZ<=QzF#X`K58|+kJ!p1FNz`aWnE&$FH?4#lC) ze$ThQwa(eQ-~e#47(O8z1Q`%n$biUz$U+8021FJzATl7bkO7eakqv?jh%974WI$vg z10n+=3mFg@5Lw88$biT~24u*akmG(d^XeP)$KzsLIJ}D0A}a%A5lI zj=Y+(WFN{3l6{U)lsuRIP5%A7^2IhOa6kN!qM zGAAycz-do(;ne&^oU&Mp|GRS1V|(*~(82QC>3c;3HBB`?(HLRY$W`XsqDpK}rrvZa zp7OD4W!4vN71^J;mu5Y4J3r;V5CDH z3Z#TUqvatdY|An}bG<$fo_7{w%++Pzx*txvVwmJMO;M<-%gM|2?NCR2)nfgk+;_&x_1L&dp9DkcN608Z9&3& z+Y$F(9zq%y{@Q#-&^iSzffoOF1u`K21c>CY$seqZH;pTC=$-|qTXW&mH5)G1X2ZQ} z?f{JIOAyqv45M$XMCeTkh!}z}{?2A3-rb6nyW5a@Z+m~F+}noaN86G3bSHwU=04L4 zvrlG!PfnT+Wk6m9A}={)%_!Tc*7ccR+uxo8hikcT?3^WmacwR1*->F9R|-B!{b$?!L;dd*(~~>$$M&$bmy=E}RI6>$N%X=$Z%b?gj9>z8HZ$k~GDX z(FY^>ZXVKTu+tyx#?*)Vko{;sW;}WqGaetH#{-y7-)B91hv4i%8UbU9N%~+XyiR0v zDC(*j^pE~89tbA^qBqlLhwTjl(Uk++t2wamoXM-hnbhG%smil^KBcOK2q1Ngy0IMN zZmy;@#b9ifz@R~9O2~e=A32W?V)o<1nET!l%zN)B=DmLubLjc3$A@@G3>Z@jgThjn ze^Jf@Wn)bd$NkcQNWb*w`@L&>GZ!}32u8<@A619%^+o-@5q@he8TTe6@i2BElVD7z z!Oo>YXAl;?e;kY7KZzwzPGKp<;wLBhZFA{o4A?YM3xmR7#=pM}e&xAOl?>F)UIilm zO9P^v=DN)K=1f?3&VbF;>9FYsG80bM27vT=N3c{KELFwd*}{7Q^9q)dm;&a%cZ?tW zWlv9I<UftQ;6?AB;8nmB!9Z;K_#!rcT!bwYn?Ab8gIV)oKChkyl)hMcV=9>_RY}yH4H$iU z)eCh`(~!aG>g`WiELBZ*TWNEHV6yn&x)}1^AfE8^deS%l8<>$j$- zC#h`yk@NE`u4C52>=nNNSXmny0QSVZY+1p!(6^c*&QaGpREV8=&=*h#UA)UofgGHiTu z7I8bX;65P;A*+)xyLT_qWfY_0z>ZYPFeJ&H`ni7 z>+3nNyfO_|ZCOL046d?RL+H^p2fp3&FzWh3g!U{!?9CNOre<(*?*?Su%R?^p9rGz= zEv1yTno`z=CufjH2ELsI0oqBi>**QHEL;XFZ!u_a`@@{R&uU#qCchigZf!u?ja5jv zzKqK0rSK`8@=Tzns3ld1{96a4uM<|#RS}w(ru~M2U_dNe2cSrROy_|(QkCUOrtU>R z0;o$LOFj}qP*Mm=1~rA#3CbKY_Jw4~OUXx85tQ|hk6_Dt$C3B=D2_ipkEZ{q$BoZh z(fX(osj-33ljC5ZDhC5~c|PZwXDPA4 zSKt(h$Pg&XHhP>zZN{6d5XpgPMA%GYsmZc=Dl9Kg9RkIgRAR%YtsFRY%!C`M#D^k; zz(iBEHGv|FVlJhzrQM6Lic;9xn`^PYcMCS%+l{;j`;m8lKT4lo#2nYK-*pD!jQttWWf+NWdp)m-f9oR2--%dzLidhEWn1;_8~#qU4Aju)Ty;Q7Zb z`2J}vUOcJ9%a3b;uexz;RVo5S9LCuyBho>DMAs3R=%R#a!Rp966N&9tCSyfo8fIR} zKz#MYuSH^2S50M3O~9bYv+L0kC!}VUv*3XwzPUi;)s;2q4S#OgoC%ADDX@G63a=6d zgu;mcc+umit1}QwATnDsv9x6}wp^ZwcbZdivMCwo=rNzRooUO)iH>w=Pdnk4Qded)?boijNU%UM*Xb7p4}`E3GweM(=6oQR-^ zi&8nQWG7D5$COhR4Pzk6*18@RwdpUZ!h%J8h7^i4b+t%T!qS#qI|DKu-t>G7K}u?! zf>|w-u(l}$jir9LU+ji!C4T5A4?FP}V#N1ua=F5R=85M=902l%$N4GPoS;mhhOP1HxRkDgXDbcx+ucHZx>*}HR|!#cApi%e!m*|~ z0SOy@nw^6TrkeU1Ch7VaCusPar3e@LPY@NRrd!la$rP8SWoyRS=ju-P$`)UmkRdLa zIK{kTQl@ZOP?AQJt(}swhU7+=;xOz()I+VNGIf~Oq=O7m0;O@v5I5|krXrP8Ft0HM<)uORYpDTHq=T0i_3@XJ2Ke~A18!gPMN3U2>IvAMGXXd= z7TB!`9HiGC(!q-Zn)qA33!2xP;#{sOPG+m&{4{lZvsWKDAp}ku0tFPO^zf_QW+*NW zz@Exb%&Cb*Y)Ksat5V?7luqi+qO_VVsSMd;C-qLZXTjzs^;E2k=YuN7t{Jdu&3bOM zGrWq*eAB*5{KEzar7JD%bhoW6O;NcB^Xkb`C{qTYNL6A>P#o#NJ=>;X^pz<{xjY#Q z8&c47+6(`Azy_ZlwZ(U5^zo7g@9!t|DRl6#z!|j_V{m$(I}Y#kK<^oE{GSVM_^i+o zUthAo^HM|n?VK(i9ydnUNikZFS)%2z4IUh|!Iyij@RvLjyf|cp7X=3NsE^*G4me&B zj8$c!NIesZ;DT7Vm8HP0W)iHKvRRsKo7UghzBUM!?VZ`6O6-xmhJe5CGHie-=&PFQ z=8imSNe4rc=Al?HrPO5%_=!{{HU!0i&Ol%CkLZqBnA)C$6*K?`Ym!h_5{Bl|QTXJP zHJ+c-$BTSYz$s1q?t}q4OGl!%E)Vg!rz_1b=QZ z#aDF}c-ZKL?iyd*Dj7+s%oSg~Yl*)eWl)6p@`x46%0^*(`8Z@A3&yw;;qbVS0Q=HZ zSkuX5DTTt9>{qk@Vb~B9oh;Aw+;CEel8J`3{-S^aa{^#qo;CobHhpO7Vh2f3Sjihi z{YOOST%@+oL@sUL&^Q4{YolqPgV9yujnDF}@ZzElp66@h52y4=C3dK;4#I`naX3>K zfr9!l)HDX;TGL2;*Wh5l#x3aAhjyHl<-3RX}H} z#-Op>2X`+y;V=0#$R*nNrc8)iWe%vKGyYWlXdGw^$Kj?h6t;xma@$DUYj?t*JB@&Q z^!j^x_^itUJ?*Y&ZSlnAI&ZXBc%rAo75^{a3@FpXHRtn{xDTPuOz3v;Tye17BAd1H7mQ=f+w;)xBFHIbPQZ-3p@_ng` zOy7n~-GQ1jXR5Y5TC?HbnuYL|OiXH;h$Z!L*jF1n1tL7ZqzBY%QAul# zlDd&NOsd${9FA=*;W*M3g36AO=<0UH7ad|Mf62rj>Ecg!4bju-h`M%9R5f{{q1FTK zm9F@*NQ9SFdidjMW3*p%!HMz!tgQ+|dVL}SPesAuP$Vo*$3tA0%B!5cZ$90!f}}m` zM}d$(KG(@`pEZ0uL|4U#^5`M+N&-@x3MvmFE+Z%vX#;*zpV99nR+PSMDI5rpds7Ai z8z&*QJ{38nkj(_-e2ouUs$KAm8FnS5p=K?7Tw#L322bp345Siy4A!)a!|t|GxY+51 zw(Cy#@VYsk-_WIgL2eEYXC0Lpf`6r;InRH;DI*qR2#p&Z-n|TClp-u zM1HF`N}Ju$)aZ<-RTg;JqL0573-QGX0$l8YHRT~luZqPes!*G(@KpAi9{! zpHS?5_p9VJsmrE!7L4DCYF0AUG#plqp=zLb0yR<)6{bj_T$(V{PiiLfDq+TNN#9#j zI=LvfYMQMyED4lE%Bn48pRJZ@%XwK z`HBMy+gxz^iaYXK+)>`*f-9FD@l}fna90m6FALFDVUPV)K2&9eAcazv-&v}%4n)A> zWE{klvP7hE3swR*OHG}cLhJ4vY7%oLjbU5X3!`1(^#TW>W#6^DVFg4^peQij9q}O# zUb+znBE~i}4tBF%I!X5y&kWjm;H)I9ct1ih5^!P)}#` z9V&Zo>fvsq1O=mv7ge|#%doduk^#pYG3Sca7SB*6?(6V@O`fag*u*)qRJZW zaJJ3~$EsZkt_$+X%p05S@%3#|+cQ$z0|V4HIpScm4_4L&BRS8b)6rJNM^}+k5cJ(^ z*HGrv$60Zz{vuA%NS$4$Yxn^fm}wGiMshc0 zIhc%*2a`VlMqETqSIGp}QuF0nk&1w-WJHm7tSq2viMr{sG8g==&VbUC7Vy3nKD}y+ zq82y2+v0;w&4E}#WYp&%N~89u@rkni`re+u(GQ8xGZb;!u?b z8j7uOt6Gfz>N3E~$K){|=;C84kB_zaVBJ~Q4^tAg=XzT!xQTS-jI~tdw3HP&Wd%7- zo(-?ST$_iYY^lSIa50bo@-yR!ll(=?uVz zj?q|fH5@rtV=#kaL+2Qjbi4EB{h#f6__|UPw;Mz_(dvbLEq=%&cn9jJxhyurcNOaR zbCV7_uG-4}QB39pVf z4~RTBaMv)_ZY_ggayS;IN8==5P7t6|R7w&U^K*%?x{wH`f&};$#Ut!eEGCvlU}H%D zD$1O2iP94@@4c7(u(>q|%Uj1Fr!@j;S7MOd5{J~5SWKs;aMR@=oTmPwxXKZyYu&KD z*&iF50lTzUsV%~Q|0bxFR?;(xjp~$&6fkPx-|qj`M%FWyp_i|m@7CK>nj** zsB#*-I^-pD^!tLX%#tX?@J&<5z|;)|Er9{4qcoOvKp6B>pk6 zF&3E(;h5Pt4s+>s^C{*v5V-nr$gB%TMok1VYr>IT6NY)!W3Z5Vn+0{FF}r>YGMgeW zCc|vKoiQgi7AhEPsdHKaWlliqQ0SY5GC0^hj}fkKDiA3YwLnp(DFLB|3C8=QVe)RY z1P*O8I}!);<8iQ}^3w54EIjk62e=S}$cvFkED6U1N?#MJ!l@LEL|knQLhIrYSeFE! zx)gX*_|+vNq&5)|b>k6V7lV|#C_WNvqY+yZi^%FYL{!Bgnj)V1i{#2kq*O-GV+7*s zV-cL^(`IQTZ)T_~XP~LZX^v2q+*4=X@hS`+h@L8$`5O*|J?hQ&sW&+g1LHjrFy0$E z0Ef1T4#mLyXe_Kx#K7TH4BXE~!}mOaDU3l#5k*NXg372jD36C%MIu})li^gA%7<%J z3OuWl;9Hf5!0H49SH~l`YCM7}2lb<{L97 z%^)g{RMk~Eb*VD=Stos2_tj9O7qjZ>%>we8FC`OAC!@U3ucNKn%2HuR;aHvm=kjE@ zmQyc7;YQ(FmIN2t=3FKTm(paoQPb&Ok^uKh@o*=Qq7>V8YOER*a4Jg7Go;Fp<9_^$ ztqOiCfbf@7d`u@9?Fa*T3i!uCU`+N!!EApN#D}6`PGBsL$H4kzENo84!J7QVIzNFo ze@m*$EH9?Of+{o1;#62(N`+Mk!Qmr?hs6VvZnN(D*(KUuoD937B-mF?gy|B$QUUn{ zn_Z&tN{V{>fc%5?Av)7M%8e*(8Ezd1Qj7!+fiW5khCGI)F%hLPG5L%5B$+=|YGUeR z*kuec>thO}y$ppp10;oHQ7jE=K8J?nHCAO4VX}U7hoYL2Cg1c)KnyYOUyMTdsipJ$ zdW`o(!f?wtNo*x3+d?IZ*+q)kBTZw2jK8lUW2Lg$Y3gClCJi*07o?YE3ZzjuI8p}% zfh(B^!;NEa$qN+KahZ!Hiib$=L|%ABIUs)}$;$R|cS!g&z=P__(G3lD|VvTwlj zhx9Omo6EjSGJS9c1L7lj2q^YD+7n&2u=!I8N(#RmAR5uOKa40FPBX#5l+x3;ObtAc zSD+aF7?guCuW2mfC2AQ2hF48roKG6Ks7XK=Sau?4#ydZjpa&^`mZ_jBaJ8^1$B64)OUnmeK1GaEy85>k)-V6$_l)OGDgA}t>suos-vC^1N zUD14(Z%U1%#8cuW>Fd-WAPfe9Fe7C!Xbh~u+R^-enL-HW@3oShgqpE-oMs$BNp$1~ zR*44rtp>v0@T(zk6mt5D0*cug%QuB=peZdG?TX-2iQ%>|-bebu&{=IvKV!;Zzr&mQ z$w8`MgU?dZSxJgwM$aIyGMYgUE(?Oenh<{9Y#$o9kOg z1AWzCO>npV(x4Wq*s2KPUk%oVK!2e>^yc{TK|h1xhB5s9Ob^HLsf^t=He5ftP{6L% zl3ITdZibw|N#ZSR7Q3Q>IzPBWg0?A{X-Tg3hQ2{S*v*?E5h&u+$6D&rnf_nw3}qFz9Umjl8~gi~L(n>0l-)BDzHf@K^{kodX_7}o_mz~-FYA~g+G{U6+LrkecfB{mq$h*_1SlkIhgfiPG% zny<>3Co!0;{o8b0)DlCNT9=H-UhX0OGw$PC(#CCWCVP{QWC|PK; z+-pH+>bLxADjFm<+l0;8;=!=X8U@m>TH0-kC6_pg+2AuJsD)VY6AaiYC5;Fh@*{#Y z+LF_s@87}qEmTRd(wK+Ae!nzL0)r`oEimnw$vml*8S>!w_Adv!dq{1KQ7vN=rr5`-qn5;qB$$r8nsrAelnUXldct{!fas3=t9mBH@P32bzEII006 z37i0tyus?=r%V-mX-w&Fh%%%w_}PRvbD4?`DpB>smZSYUV}yf{V}*i%j&<11IvLV` z&>JSBZe^3n*nC)i(dS?=Y~nSUE}LE|S+bD9jQ?{2sjg&3FvKi9X!50|Y9NEba=0m{ zHcG5-v@85;RvfT2$HOR*%q)C$*?{$pnXE(4WN`nj3K<-9;wk8>a_l7Po8&QkQkIn@ zx3a-h^)I%8(;>f|A6 zW5_=i`mf{D9QhDG3zETLlc3qG^jBu1llp$GHp*O+P7aB}ey#`*vpLQE{nzj^by5hO zF{(6Z&#b#={NtryeULg>HI(s3`aKgqA2W4OzoAV2p%G=v8#-_51jJ}-Xd$2KSej$= zgPSv7zeIp3S|=c|)f2lK~4?j5<4{ zIcFcNY$8z|E2GIVD=JKBg{IrB2!|l?}j8h0(uGuQ~Hufk`IXxBvhF zq)9|URGq$z*8TW#A^?Ad0m)W%Hjmh7Az) zv6e2zdn3zi{-;3L;8Cj6p5mUt&NSA`FlA8h!FTJ_k$3!5Z|XPr_U!Lf1I+A{%vsm2 z^RvdV0ir$GZ6;MeUos#pWw9=u4IrzwSQ*L`z<i7RNanuAcwf|dlOu7P#6_vwEGj4OAO)>A+7r2+Qpgr6 zUw4{UOxj_%aqMcNT@mX{PsDH0UlOoP(NJCTDbxz`oV+qsF6;yKsSDPOwF{xw?;_}X zjdq6bH#-@>kD%{0FH75FdMaU`(e|)?qH{?*>2Kv3zZ<=QzF#X`K58|+kJB<0fC^F+RBR|9;SB$bAbRD+-bqLK=T3W!Q7ASxg#seq_}sH6g-0-_oO6%dtFKvY0f zQUOr`QAq_v1wH9v+tUw(zN~nh?rWOs8|nwyPBg0+zgV_D@wCf<+`FD9OF#5( zt@y;JrSjLlO%)&c)Rn&Bu|2y}wjg?oY5Lfl5w4~(HHN^0uY{@s@(%z}YJ{c+IU&?? zQRIG?=8|7~-X?SW;J0ZdV25hXRq*=r#?Ueu!PX?XI*QkG^T&c;9~xK6hrp z@8&E7^gV~bn{yF-dmh5>EI{O)=MjB(F=Fp6MZ&Agk#v70QtrQi)cdQD{`wkZyt4tR z@2o@Qg*m^GRfR3rFw!v+@2jH%@^^s9M}+c&lhvx2)9yE?!Smisc=k=l*xu>z?VC9O zlj{{MckA`8Q%Vej{vQOP!odNgW8hG?flf&qp3ID#?7=Lq)9LAl6n0U8V zxFYe@6-a%sN`T7p||B>ik+c^ zk^R~_6wqK7zquKc-`a-Chucy0a0ja1-bvRxF@^3|y!8^n*@6NB#*WE)e-i@sm)y`a z)-x9$Km|nc?FfiTb>K#qI|QO{DqOBlgIQJ5a8&%)wjtRHs_UDbbd&?+suR@l9u@PkiV+sv+ z4GlU&nDg#F%zO6$=D&9k3rO?cJ0KpLNzXB`a&ikpVVLRfu1CHKN2xL@&_d=(;)o|*mg7ft$aP9|E4bR>IAj;ekp>PL>s`LkIL{8vb!6AtqF#Dao zV(=F}I)vIsN3i7mqoiZv_9A+WpHo6%r?9g!XgjIzt%Kjel3uF3bo;~C_v}PwwGop2 z`Ld@Oh}uxmMc3ad+OfOxZ%(~ca3UB^HwFW#ffqT%hk%H1Meg9-5hW7&GEvs@-d#j{ zIq&T?G{Ec(9`NViKa8aWVfhEgvEmmeu#&{L`7wTOF1?0B7>6&0$rTxw$Vu<5fy4ah zoqx|A-1%E=O_c1<|My_uc)%1?-3wADqCdUo>F#hmBZ6;@c~KK~O$8CfxHJ zg)a_o<>Zol3VH03#0M)8b${{K2L9HO-v>m;%~Y~EkS@vEi=UB@#i6Rmr`Gun!RW5+ z2jZ-Bh!TkCJt%+l$*ZgILE$QcN?Z;%9CoHsCB=!G^F{6ZM}!+z6M(fJp2Yf(P6@4{ z+iQM#5^Fzc!itX@QTy+8nE7b0C<54JS+u>RS65P(zXINeif&1o>RQTzLya{Eh+(=r z0m*pUfeeHyEgM4@`;Lftubp!_lKoqc%z(P1q6ppL>*JvpQvFT8&o ztH>>DKCDM+{bE@9%IJeg{W7Qfh25)B`TkDi5#Tg-2mz0}Ukl%+@(NtDzxUtNX* zY6imhN$tBM{d8uP@@WzkUjQ^*6b`{(|&ZoH}tBBXzZ*P2-}YNg^;5j$mM>kGLb1$bYyB zDYq74Qr}!e-k%4z%}Je#kflC&V&&NYqPUnZi9E^S$^K%Q9LnWEP#B0JY;mXVMPbXY zZ#shdW*~~7B;0xqS$F25@ZLgHyt)|E9<0D@O2+fvd=ZPN(yApW8z^M`{?ET727ktv zfBPf8`s@GT>%S13FaHR>ELkuE>I^}Lq%FVJr~4+Rx=5%irCjnn5_@JLnnGn@NBMv2 zn~bp5l*GJee<~SW<|kS2dj^0|{XUXD@W&2aWw1YA3Wvv_$Xzm!N4yA%UvCY9$tlqU zCgtV~d*g; zumATy@Xa4SASk~>@6}d}A_yk>3h7ZUF(7G4klE=YxuFP|w`U^0y9!aaYG4^=m#L{p z?0nHQ)0a$U2T9g1r^taE&KxL(k7i1?1jVi~SGY(o&|1>A9mYVkos9kL&lP_|6&CC} zOB7HPq3g2TB~A*LxDpgEsu;yA3YAKv8y1NjI?=Qm= za?0~>Zo-}qPvEOBKEpSE`2)WC(|_XYPyY>H|K>G(^UF5iZy%!R*cO-*1l!RPY)JMb zM`H<|<`R63Buor2LT*bQ(yvz_u5SuFmxVQ%_?e{``CB9y1X!gQm-%H`Zj8;fJ(gW; z-%(m-*HlnxnCezzJSCvg?o?ih-Rb;NSxaG=*}|}_k%=y@T2>?F2f{RmVIN{J$#F8f zLw2?p)aA;dTqqrqPlQW2Y+bK{C%MFzpiCe|_f#R125D_?5_aE>!@iz)?7fg>bo424@jo6_p|NPmVp*JH0v$ z&UdM&;xb-{D#pGlI9{#z(sEN=8D25iI&&5qN8^Sw(g&R*~=Y}x6mJ%&yPp?qVY(cGY%Qk{ZLfpiKTO7 z*f7l$TT6^F=R_>hFXtn=BNu*0lHpOG3FkBUaBMG@e_jr=*UI}F+b4=(xjdK-o1<9| z)ko@x<1WJnh=!@2wQAyi$(QFWC;D!e@h zl{aT%9z9oktqfZ)WDt}j?7fnNjTdto@mi z|Atz)6Kz62J0Lr=Ip`nZS zJaP$7ECv#c&|7n;!kU9Px}8RqRvsnyQpzXQJr!7VB_EqFCE=ADldz#X4YPa7P;qlA zif(c8pDk2K6z%>Fl67dvb-{sr&&bZH4kAuMAz3^qsF&!u1;U zBHdHrNg8{d%3rz;q*64Tl4)#r88WUGqUc%+K#?EkTzZFbXS1j^wMCv9H4qd(Zo! z>U<(H>G4UI^ALQk1g?iuVfS(p><(qXwjo!zoIke+w;XD_E4~v5<;O2am-tQ_J~_l# z*OKDsZdoe1DOQxShP2a&YLhg~i}3CwV^JL*MWBR32vxpDIgFOP?&eoWqoDBLO*?C;vi2 zLKo+fG7$zuUQx)QqZH0`?cP}g-_8OAb><+ZGacy^Udql-!uoULC}jC!Q%?Z$FT^9J zD+6H{vJrGX2Vosqh&`K*toB6IoQcAYlRlKNy|KN)2jwl%$U2vRjE+QPcP5~?GZy8Y z(b#pt8;38uW6Iemq;(`AvLhYiFXq9mF%!01;$Ztq3aBAexTHXQ?tYg%A#^$4p9ZU! z61%jl4K0RMW2hHumq(2hZ0mF6P)_9y%_nDz&&FeFTO_u1_+a<#u~>C^9MU@y5JP2g=-CVew`C%{H68J1l9AmUhq(h1kg_4T9*!+ z7h_?wD;YKiDQum{fs8-@*+IGFYQ=y{6g>)c^uN_{G4UH#Wv^lZoV)F@tS|YCJP`^5 zP=qc!N}4Pg0dycIIXC6O<8%)Enllm7oQk;SL}bul&TbCDt}ajPy6%N(EulziPe62Q zGD6OzBDgsX5vNm-a54e84KbL1Yy$QkcE_Ppu2@+gfYOsuC^|h6Ma`5?S|d@}9)a4{ zK-Bj-p}x;aY%h_v7v7eNfb)59IhF>yU5T*Wn+lslnZo7v78e78p4 z7+$OR+VaJ?P91kM2jyJeumYl{qp4%HIsO9yq%NCE!5m@xZ-p^tm+y(ir;?RW^v>cdgi5P`|3!co~AhIws)*w^KTGxzLq;HoPMTcQx( znt(7WmpyjGyltNCx@~lZ+b*-&K|3us#I84;7qZIqx!{$fEB%+6%$Ts;d~w7JrVBz> z8c!Slym8gI482fWM|DFTH4S4uu}pT@0Z}ZUIbc_x3!5XE+`-Dh40cPiqDLX8h$@DF zaqaJVECXZfQZc?R8R2yah&vvO{Q5|2YV^Y1Gp?v;3_(KUBt$pFA@oEdg6a|xOo})b zkN6{#kbO7`OAq?t&>?3mK1|{2NEk|wg`wnl7^;s4V{YSkY`@@v<~|wfFFBz0v_I0R zSBYs!g!i&>oue&uWLk=YRa&D)NTUk9`A~wSH^D~Iv^3y(I!QmwP8#83DQS)|E7_BR5S{MvNAOkB+lDI;#K0xu9%0~g_*Z`P*w{V?LE^(re;M`sa_m({Pp22C~J_?JD2Vw6) z53D*8ARaGmn23rK5m<065PR#~alF+TCp#R`(CLKL=loIB5rawF#=q+7uODk_AQ>8H zNjlnElD3AL{J5u%t&wDy?k4F+$Rurt(b9;q=8{2-qofyPBWXL1mPRHxOFHhRTwM-t zAnLkW`egSHZ3u`pm5=>k4lBSMCol~IU>wg-{%9?L$Jqh|oXtZ*8+GKTBC(P>>7}Pb zu;gS2(mN@qP%kl&O5w1}`3SyJh)^nxlc>|KX^q8#rYNkg561EnA;@n_Le4pA_|7Hc z`O{%&sB=ZzDMz$6JEE@54I9q;V=^W8^ovRGjW@5b(v$Q@8%U#cbtGL)4M~&FW>6l| zrJYMMh<12NfhZ47^HIYT*JTW0%*!dT-jgZ^vp-!_F8z)nFm{|jsAq9HoeQ_-T=<;H zK~PI3CZ0*7#GQ`V_B2t_PVC4;*!gTsIG>Ag=kwuzp5Re=9N3vp6;cjTD8c7a5s=VE z6&ERyl5|o#Jw~pYbt(e0o5HcEDHyZb!;nwaRw|deyTjkHwN#UtjFgP^M@ahGn&b|3 zNkc<%Y=ot0pe^Y~+CQxh8CWTxVWeYDF8P>&jG+>8%x=1-+TNO~7wi25=U{rjV`LP{ z94MhXH)g}*R5rYuvf$rLjao|8QNqn!ZJ)h zy6;MIqk_O=kUU9VExGWf5a`>S4Zo&L_?^xaJKd7g1N zou^Q~m>%cj7D_oa=M9lF$%Vuq-I{XXPN9(Jsdy&9JkxbCm$zCP^iP9whMHJ$@|_o6 z;PA`<5z{Gw)`gZEV?j9u;(9QcmlR-j6PQ<0ai#0KFttBYyC&?Z2B7xa5$Ss4yn7ks(P=LuAXfTyWTY?mEEFh4WO_B1n0ag_{H2?~SB^5Di* z($v>_c7gD;^yAX;Fq2H@hMeR*Ry2h?&=i&|UyK)_#A1D{$Rqt=Xs@=S=hzwiHzKJY z7~~2bd=5!Rb@QbWH%%9WU8ahyjUfKTd|4z+=LExK#sndH4i+mXitSmyoGL;Y z9}Kft5mm3lb5Z2hCu%Io*Yb%wRKMKK#B2E&$WsG^58ezBg#?3W2V>gP|G;}VhaHg< zC^rbV3=xGU?nMX&?d|`iZlG;4G;T=!Us%W0#AWnkzb{BIo;nUDvx8t(8xD)r(ZVVG zKDLS#BfPqWU~U{iPUT6$pCp22Fwy?$0is6`21}PdIK}EnZqhi^aOmMY&_4sbbC5)* zo+9>Y`lD;ec@NxBoPpOTOjXgx$Dye)WgaXv4h;jWsiAkG6KF>`*P!Q<%? zF=e8tqHK<4g5r7_hY%f4v;JQXQq$6qbjOVmNAGBG=a|k3p%4`cvn3IVN-9BYvmXX8 z+u^le*DHB@k^Hy3Xa7{OQ%3k$i0SxY4}_094;Ft=3L)3T=?P~F#2gg&1_BIMM-1nn zT*?DiG^oF$++obI+JL^WmbIa%a(FOA5~eC?bY;M924TKDN>pW>lNhEr;Kgfl&lSs; z>-1Fe0=LhourT9e;96Ab{xhU)KU(1sm*EYB_Zp?N>_>4zx2HYzb8$A6SY=WurZEH< zp4K>_=&BXnHt*RMFGQc@!DlD%kvhF#TXB{WFE%iUCP+~ZlIiT=8=`NaN{UNk0fYa( zNxl|WID=0xyY>8h5E(U8yflf@-4C-_*WVP5u9C#)3jLB^E7746n=L<))|P;>Qi*oHIqKNzUMMQ^(m@z|jk_mBR_KRX1M}@kmUuaA{28Z-_G# zFvM!YyEW{hU0PJq^66;*Oo^(C3I!eduETcK$&mhoJ}@QftGt+u*TagFJ_m#0h1a|c zsJ%#W%0dYz{*MWyftC%yu;cJxC`wYjP=>)V+*;BPw==bTG44|?4#djB<8o*5lA^~? z8*sW)%^i9f!~Lf^WUy$*(=gQ&{fcst$M6YRj`G;bgQ+*c+LZ?9OEEaS$MQMrR~6^2 z^Z6lN3OE{`V)6jr>rxcJE>?{|s%EgcsVJ{3d!w5>Xy@;iJ^M;IxjZZv|cs~4Q_)eHkCBNkBB6_8UL;@Ypp*F&ufKO*-jL<|lz`2i4?i-bIp-f%9wT=hm(i44w5hrLNEzltPP+Qt zCuNHKb$RliD4+SOQFAGNIs5-X!zZcxT8YZTa{Z)z;uPW^0fd+JlT*H?5Ho?3xyVOc zUeflsYU5Bw&$*E+zLcNy{@7^&-vye&ruEAy-QpZ_9S!-fU;oS+J}2zxYH@Nil(iIm zB9`j^7$Azlv)mY4&k0glAh6@~BV}U2v&pQWsp8bJ{vWgXVcX?ui<-)OEz6PertW9f z@JZ@sdelj~=JEjiSQ!21>2;NTuH$NI$IJUQ%?!kpx9)gr;S$SrlMabc*!|vVf6 z&kWoZ4WivBNn7^wYS;iVh;|rjwKbvH`5y(sgGZrmRH<(X?`ho2ursLl5ZyX;(sGEN%e!o$<9o|N_+*#uN6px7?+*G`e z_$-RY32LCms1e^j2=!0aumPguWo}}WKQ`I6E_>scUCA#{a$jn-Epf$|S5jBmHRi6j zZ!OwL4q9QkC1C}HkTq1kZj!YWZnStIdWq$W@yo6Er>`-cAF@!>!a)8j)C}qr!2kdN zhDk(0R2u4%x;9lV{Db<`1skTgM$+qFBwQUOr`QAq_v z1w9Sn_0000B<0fC^F+RBR|9;SB$bAbRD+-bqLK=T3W!Q7ASxg#seq_}sH6g-0-_oO6%dtFKvY0f zQUOr`QAq_v1wH9v+tUw(zN~nh?rWOs8|nwyPBg0+zgV_D@wCf<+`FD9OF#5( zt@y;JrSjLlO%)&c)Rn&Bu|2y}wjg?oY5Lfl5w4~(HHN^0uY{@s@(%z}YJ{c+IU&?? zQRIG?=8|7~-X?SW;J0ZdV25hXRq*=r#?Ueu!PX?XI*QkG^T&c;9~xK6hrp z@8&E7^gV~bn{yF-dmh5>EI{O)=MjB(F=Fp6MZ&Agk#v70QtrQi)cdQD{`wkZyt4tR z@2o@Qg*m^GRfR3rFw!v+@2jH%@^^s9M}+c&lhvx2)9yE?!Smisc=k=l*xu>z?VC9O zlj{{MckA`8Q%Vej{vQOP!odNgW8hG?flf&qp3ID#?7=Lq)9LAl6n0U8V zxFYe@6-a%sN`T7p||B>ik+c^ zk^R~_6wqK7zquKc-`a-Chucy0a0ja1-bvRxF@^3|y!8^n*@6NB#*WE)e-i@sm)y`a z)-x9$Km|nc?FfiTb>K#qI|QO{DqOBlgIQJ5a8&%)wjtRHs_UDbbd&?+suR@l9u@PkiV+sv+ z4GlU&nDg#F%zO6$=D&9k3rO?cJ0KpLNzXB`a&ikpVVLRfu1CHKN2xL@&_d=(;)o|*mg7ft$aP9|E4bR>IAj;ekp>PL>s`LkIL{8vb!6AtqF#Dao zV(=F}I)vIsN3i7mqoiZv_9A+WpHo6%r?9g!XgjIzt%Kjel3uF3bo;~C_v}PwwGop2 z`Ld@Oh}uxmMc3ad+OfOxZ%(~ca3UB^HwFW#ffqT%hk%H1Meg9-5hW7&GEvs@-d#j{ zIq&T?G{Ec(9`NViKa8aWVfhEgvEmmeu#&{L`7wTOF1?0B7>6&0$rTxw$Vu<5fy4ah zoqx|A-1%E=O_c1<|My_uc)%1?-3wADqCdUo>F#hmBZ6;@c~KK~O$8CfxHJ zg)a_o<>Zol3VH03#0M)8b${{K2L9HO-v>m;%~Y~EkS@vEi=UB@#i6Rmr`Gun!RW5+ z2jZ-Bh!TkCJt%+l$*ZgILE$QcN?Z;%9CoHsCB=!G^F{6ZM}!+z6M(fJp2Yf(P6@4{ z+iQM#5^Fzc!itX@QTy+8nE7b0C<54JS+u>RS65P(zXINeif&1o>RQTzLya{Eh+(=r z0m*pUfeeHyEgM4@`;Lftubp!_lKoqc%z(P1q6ppL>*JvpQvFT8&o ztH>>DKCDM+{bE@9%IJeg{W7Qfh25)B`TkDi5#Tg-2mz0}Ukl%+@(NtDzxUtNX* zY6imhN$tBM{d8uP@@WzkUjQ^*6b`{(|&ZoH}tBBXzZ*P2-}YNg^;5j$mM>kGLb1$bYyB zDYq74Qr}!e-k%4z%}Je#kflC&V&&NYqPUnZi9E^S$^K%Q9LnWEP#B0JY;mXVMPbXY zZ#shdW*~~7B;0xqS$F25@ZLgHyt)|E9<0D@O2+fvd=ZPN(yApW8z^M`{?ET727ktv zfBPf8`s@GT>%S13FaHR>ELkuE>I^}Lq%FVJr~4+Rx=5%irCjnn5_@JLnnGn@NBMv2 zn~bp5l*GJee<~SW<|kS2dj^0|{XUXD@W&2aWw1YA3Wvv_$Xzm!N4yA%UvCY9$tlqU zCgtV~d*g; zumATy@Xa4SASk~>@6}d}A_yk>3h7ZUF(7G4klE=YxuFP|w`U^0y9!aaYG4^=m#L{p z?0nHQ)0a$U2T9g1r^taE&KxL(k7i1?1jVi~SGY(o&|1>A9mYVkos9kL&lP_|6&CC} zOB7HPq3g2TB~A*LxDpgEsu;yA3YAKv8y1NjI?=Qm= za?0~>Zo-}qPvEOBKEpSE`2)WC(|_XYPyY>H|K>G(^UF5iZy%!R*cO-*1l!RPY)JMb zM`H<|<`R63Buor2LT*bQ(yvz_u5SuFmxVQ%_?e{``CB9y1X!gQm-%H`Zj8;fJ(gW; z-%(m-*HlnxnCezzJSCvg?o?ih-Rb;NSxaG=*}|}_k%=y@T2>?F2f{RmVIN{J$#F8f zLw2?p)aA;dTqqrqPlQW2Y+bK{C%MFzpiCe|_f#R125D_?5_aE>!@iz)?7fg>bo424@jo6_p|NPmVp*JH0v$ z&UdM&;xb-{D#pGlI9{#z(sEN=8D25iI&&5qN8^Sw(g&R*~=Y}x6mJ%&yPp?qVY(cGY%Qk{ZLfpiKTO7 z*f7l$TT6^F=R_>hFXtn=BNu*0lHpOG3FkBUaBMG@e_jr=*UI}F+b4=(xjdK-o1<9| z)ko@x<1WJnh=!@2wQAyi$(QFWC;D!e@h zl{aT%9z9oktqfZ)WDt}j?7fnNjTdto@mi z|Atz)6Kz62J0Lr=Ip`nZS zJaP$7ECv#c&|7n;!kU9Px}8RqRvsnyQpzXQJr!7VB_EqFCE=ADldz#X4YPa7P;qlA zif(c8pDk2K6z%>Fl67dvb-{sr&&bZH4kAuMAz3^qsF&!u1;U zBHdHrNg8{d%3rz;q*64Tl4)#r88WUGqUc%+K#?EkTzZFbXS1j^wMCv9H4qd(Zo! z>U<(H>G4UI^ALQk1g?iuVfS(p><(qXwjo!zoIke+w;XD_E4~v5<;O2am-tQ_J~_l# z*OKDsZdoe1DOQxShP2a&YLhg~i}3CwV^JL*MWBR32vxpDIgFOP?&eoWqoDBLO*?C;vi2 zLKo+fG7$zuUQx)QqZH0`?cP}g-_8OAb><+ZGacy^Udql-!uoULC}jC!Q%?Z$FT^9J zD+6H{vJrGX2Vosqh&`K*toB6IoQcAYlRlKNy|KN)2jwl%$U2vRjE+QPcP5~?GZy8Y z(b#pt8;38uW6Iemq;(`AvLhYiFXq9mF%!01;$Ztq3aBAexTHXQ?tYg%A#^$4p9ZU! z61%jl4K0RMW2hHumq(2hZ0mF6P)_9y%_nDz&&FeFTO_u1_+a<#u~>C^9MU@y5JP2g=-CVew`C%{H68J1l9AmUhq(h1kg_4T9*!+ z7h_?wD;YKiDQum{fs8-@*+IGFYQ=y{6g>)c^uN_{G4UH#Wv^lZoV)F@tS|YCJP`^5 zP=qc!N}4Pg0dycIIXC6O<8%)Enllm7oQk;SL}bul&TbCDt}ajPy6%N(EulziPe62Q zGD6OzBDgsX5vNm-a54e84KbL1Yy$QkcE_Ppu2@+gfYOsuC^|h6Ma`5?S|d@}9)a4{ zK-Bj-p}x;aY%h_v7v7eNfb)59IhF>yU5T*Wn+lslnZo7v78e78p4 z7+$OR+VaJ?P91kM2jyJeumYl{qp4%HIsO9yq%NCE!5m@xZ-p^tm+y(ir;?RW^v>cdgi5P`|3!co~AhIws)*w^KTGxzLq;HoPMTcQx( znt(7WmpyjGyltNCx@~lZ+b*-&K|3us#I84;7qZIqx!{$fEB%+6%$Ts;d~w7JrVBz> z8c!Slym8gI482fWM|DFTH4S4uu}pT@0Z}ZUIbc_x3!5XE+`-Dh40cPiqDLX8h$@DF zaqaJVECXZfQZc?R8R2yah&vvO{Q5|2YV^Y1Gp?v;3_(KUBt$pFA@oEdg6a|xOo})b zkN6{#kbO7`OAq?t&>?3mK1|{2NEk|wg`wnl7^;s4V{YSkY`@@v<~|wfFFBz0v_I0R zSBYs!g!i&>oue&uWLk=YRa&D)NTUk9`A~wSH^D~Iv^3y(I!QmwP8#83DQS)|E7_BR5S{MvNAOkB+lDI;#K0xu9%0~g_*Z`P*w{V?LE^(re;M`sa_m({Pp22C~J_?JD2Vw6) z53D*8ARaGmn23rK5m<065PR#~alF+TCp#R`(CLKL=loIB5rawF#=q+7uODk_AQ>8H zNjlnElD3AL{J5u%t&wDy?k4F+$Rurt(b9;q=8{2-qofyPBWXL1mPRHxOFHhRTwM-t zAnLkW`egSHZ3u`pm5=>k4lBSMCol~IU>wg-{%9?L$Jqh|oXtZ*8+GKTBC(P>>7}Pb zu;gS2(mN@qP%kl&O5w1}`3SyJh)^nxlc>|KX^q8#rYNkg561EnA;@n_Le4pA_|7Hc z`O{%&sB=ZzDMz$6JEE@54I9q;V=^W8^ovRGjW@5b(v$Q@8%U#cbtGL)4M~&FW>6l| zrJYMMh<12NfhZ47^HIYT*JTW0%*!dT-jgZ^vp-!_F8z)nFm{|jsAq9HoeQ_-T=<;H zK~PI3CZ0*7#GQ`V_B2t_PVC4;*!gTsIG>Ag=kwuzp5Re=9N3vp6;cjTD8c7a5s=VE z6&ERyl5|o#Jw~pYbt(e0o5HcEDHyZb!;nwaRw|deyTjkHwN#UtjFgP^M@ahGn&b|3 zNkc<%Y=ot0pe^Y~+CQxh8CWTxVWeYDF8P>&jG+>8%x=1-+TNO~7wi25=U{rjV`LP{ z94MhXH)g}*R5rYuvf$rLjao|8QNqn!ZJ)h zy6;MIqk_O=kUU9VExGWf5a`>S4Zo&L_?^xaJKd7g1N zou^Q~m>%cj7D_oa=M9lF$%Vuq-I{XXPN9(Jsdy&9JkxbCm$zCP^iP9whMHJ$@|_o6 z;PA`<5z{Gw)`gZEV?j9u;(9QcmlR-j6PQ<0ai#0KFttBYyC&?Z2B7xa5$Ss4yn7ks(P=LuAXfTyWTY?mEEFh4WO_B1n0ag_{H2?~SB^5Di* z($v>_c7gD;^yAX;Fq2H@hMeR*Ry2h?&=i&|UyK)_#A1D{$Rqt=Xs@=S=hzwiHzKJY z7~~2bd=5!Rb@QbWH%%9WU8ahyjUfKTd|4z+=LExK#sndH4i+mXitSmyoGL;Y z9}Kft5mm3lb5Z2hCu%Io*Yb%wRKMKK#B2E&$WsG^58ezBg#?3W2V>gP|G;}VhaHg< zC^rbV3=xGU?nMX&?d|`iZlG;4G;T=!Us%W0#AWnkzb{BIo;nUDvx8t(8xD)r(ZVVG zKDLS#BfPqWU~U{iPUT6$pCp22Fwy?$0is6`21}PdIK}EnZqhi^aOmMY&_4sbbC5)* zo+9>Y`lD;ec@NxBoPpOTOjXgx$Dye)WgaXv4h;jWsiAkG6KF>`*P!Q<%? zF=e8tqHK<4g5r7_hY%f4v;JQXQq$6qbjOVmNAGBG=a|k3p%4`cvn3IVN-9BYvmXX8 z+u^le*DHB@k^Hy3Xa7{OQ%3k$i0SxY4}_094;Ft=3L)3T=?P~F#2gg&1_BIMM-1nn zT*?DiG^oF$++obI+JL^WmbIa%a(FOA5~eC?bY;M924TKDN>pW>lNhEr;Kgfl&lSs; z>-1Fe0=LhourT9e;96Ab{xhU)KU(1sm*EYB_Zp?N>_>4zx2HYzb8$A6SY=WurZEH< zp4K>_=&BXnHt*RMFGQc@!DlD%kvhF#TXB{WFE%iUCP+~ZlIiT=8=`NaN{UNk0fYa( zNxl|WID=0xyY>8h5E(U8yflf@-4C-_*WVP5u9C#)3jLB^E7746n=L<))|P;>Qi*oHIqKNzUMMQ^(m@z|jk_mBR_KRX1M}@kmUuaA{28Z-_G# zFvM!YyEW{hU0PJq^66;*Oo^(C3I!eduETcK$&mhoJ}@QftGt+u*TagFJ_m#0h1a|c zsJ%#W%0dYz{*MWyftC%yu;cJxC`wYjP=>)V+*;BPw==bTG44|?4#djB<8o*5lA^~? z8*sW)%^i9f!~Lf^WUy$*(=gQ&{fcst$M6YRj`G;bgQ+*c+LZ?9OEEaS$MQMrR~6^2 z^Z6lN3OE{`V)6jr>rxcJE>?{|s%EgcsVJ{3d!w5>Xy@;iJ^M;IxjZZv|cs~4Q_)eHkCBNkBB6_8UL;@Ypp*F&ufKO*-jL<|lz`2i4?i-bIp-f%9wT=hm(i44w5hrLNEzltPP+Qt zCuNHKb$RliD4+SOQFAGNIs5-X!zZcxT8YZTa{Z)z;uPW^0fd+JlT*H?5Ho?3xyVOc zUeflsYU5Bw&$*E+zLcNy{@7^&-vye&ruEAy-QpZ_9S!-fU;oS+J}2zxYH@Nil(iIm zB9`j^7$Azlv)mY4&k0glAh6@~BV}U2v&pQWsp8bJ{vWgXVcX?ui<-)OEz6PertW9f z@JZ@sdelj~=JEjiSQ!21>2;NTuH$NI$IJUQ%?!kpx9)gr;S$SrlMabc*!|vVf6 z&kWoZ4WivBNn7^wYS;iVh;|rjwKbvH`5y(sgGZrmRH<(X?`ho2ursLl5ZyX;(sGEN%e!o$<9o|N_+*#uN6px7?+*G`e z_$-RY32LCms1e^j2=!0aumPguWo}}WKQ`I6E_>scUCA#{a$jn-Epf$|S5jBmHRi6j zZ!OwL4q9QkC1C}HkTq1kZj!YWZnStIdWq$W@yo6Er>`-cAF@!>!a)8j)C}qr!2kdN zhDk(0R2u4%x;9lV{Db<`1skTgM$+qFBwQUOr`QAq_v z1w9Sn_0000>WFLAPx_wo`adCQ3tW7zNC=gvqYj2%0Uvjmx0 zYp;9f&effn^PRo-zt25qBoUFMv%zD!M$iG#nGT2!h|Y9CbU<{b1EK?>GaV2e5M3ka zfapvILAt&)|QmPv|q%LK1PY(q?Z>>Lc8Ee!M>%_V&+ zV@coASTexh=vx@e*DyAauW4#1@2lTae4g+4upJ#GDUUTu9&Z*)dbo~hsI%m;xkU2Z zQYv|MR7gWALnVs@Ps!NJM!c_{`nx^)K=5V7aXdG4vaq&@_Z;Ea6!WBFdG>C<4dqvZ zJL*3U+t>8V@V(8yi0EwkBz#N#jiBdCdlWO%Ry!1imYMoHDD)TtH@*g{4#+w>Dm*Nd~G(3xIULg-Iz}q?=7UP zn~N#)#zGo#w*B*n7pqP>mxPZtbTqe<^z}5?)dBggKqNivqv0$Py)r#tC^#QWJ5987d8g{vzQm@RWQCDRUxqwh`{V6JbXDOAvvz*G`UD0P{?=Gj(n=7dJ z&MF$Vf6^!R=>etuetPO~r~~pK5Pi8dth4*x)8_!VPPgYa?Po5RV&#P}dO%?C1q_SJ9 zsNm)@3VJGkJCeRNzpoC+0Fzt7wl?BP|K9QU11`0Y|G9A#c)o>#0VM1~D@9(MOhbF8 zQ2eFolyq4RQ|uWU7^Uwlqbf9Z?N6Se#`o4x^UddJ?9H___SQOV*U=a}Z+h=Jz*$XI z0LC6u^5H6qey#4Dp`E#t_y9T}>Td@i_Tyt$`dtBti{r@e>^KTIKVEo82)rX4p(?7k z4WVi(CBi#~UwMK?UY&z5#W0?dVW5%O6Pn+9p2ppJfhOL1ktW@Ki6-BEnI^ygGPPoV z!mafJ5(8szVJIBJ5_XRJiLtA-rzHKm15rO5+Tz#xU2P%X3xIKM>^FKx+@)!Kc_ZVk zc}U!gsYJk7NezH8294cen1$~z zr}(axJ4Q~H9^Vy+-I!=edGs*^GNdZ3U3GOlsm_lj-?L-Lw-3m83ck<}M3Xy`)!xCO zs_^;}krOyqa7bbgXuJK2X#Dm&uhZ;1Z_=C(H^DZG{U>mYU(-NgPhrn0!gcaLSVoZ> z>n=cfne~OQZ|Ovivy&z7!wruz5WRthhgpJ;Ffr_4-W`HGrAN#-i)0%j3!CY;zwF z5wgyYL;heOa{h>hx{5kBFM+LQMzquf)z4TwpAgXFQHP*NPI zeM~|YhpL+J*}hi*<4kiO5MPalXn=^?qhDPO*9uofkhoRvt`cEqJd_kCZq668KYUYo z!&3mT^y3a%{>d(3OR&G>XC1Wkmz}iW)15T?=UZsfomYeiU@t4d^>W@`h$?>pg}q*L zNix(o(g=-%L~?)akq6TMg^WC`{k#v={m};ie9klpC=c}zEg*9KfYe3Zk&8;4 zlQ}2lrke;?x7Ujv&pm$*JYW$*)KYlGvQIi_1z@cBWH+t;)d6_TR?1#AhC<4RQ__=V zH2ymB&POka8l?=^<1ollI_2g(a;l7+_O)DshoO^&(&_04UljD@0wLYk+X=kuHE}^2alx-k5m%MG>xM-FbuNeY6GPX*)vI4uIKC zi$BKx&vsJnjydEMuD}P8`phvxLDgp#)0mIeQ3X7t0H8DBfvMMKQ$%Oe$NFZ57W$ks zw8E8XkfY?-K1_0d=@AE_se}#e%p4V+Rli{n3`BXVABqfQi~te@l{FB^bV|Ma1ZAKH z=OeU~Utdaf?>dHKoG7N2fR8}< zBxIn5Vxx4R{C(4?{?0R0gxr*c9F=-yCMCVwPWBmoHF^&K;r!v)p7iJg(R?ebOyAKQ znov}c@_6F_C@Oe~uLxVR>fIcAd!)Q493dQf-*KWQ{}Cv zC>PL20)F!K8RWM*_mCQh-s1;E{cxI-(!t@$`)Gp<<%AX#2BHpI0qQ!0W$#erk;KbW zX~g9jl!>ra0NGmsnOgtO3L5*~vrt&;5VBsT_S>)0@(;Ju@4onq?%lsjcklg`zWVB~ zbnmOb;Ujz{u*{q>RRA#t474Lzm`G%f=XMTel(DsuO5S~vGSC51E>EWDo~HjbwKsFs zR}Z-fsUG7dInI1cfIz=n;RAoFJk~(ohwDlC02J9v1}64!NZ;t*NtB328UZiKg3>C0 zmz2Xx>Jj(Hps<^Wur=j27lrF-%P)_M#{cr}U+Am5U(i=yenI!Y{0k8q9;Z*85Mhg9 zSOSK%sYFf|2IOiik-MiAW$bFCytk)O8fu`#tF2@|%&V|3uOkOqW~wBIDe;o~i+M7T zH;VhE@TOwP6HvT%mP>|CpYwts0k#|p>8j3n}oshjm)#oJu za&A0;Oh6sdN{JUHQOc#MR0J?p*j8VeO%2E;W02fi-djy=@2#b_o9k%pe|EtuzNGu` zjIaLu2fFv?-_!j+|CZ?U{}Dj8ytz?$2---%aJ4d^P#0s0^D(9bcRflRYDYN-M^i@c zM5ww6q?(t~VIA(2X&L66VV&la>o7gB*k#$M3eU}@wcdy78@xKJnyvE#TI|L|H+$`> zsPo!gS+Cez-GIbjVwLUZZ{%tv-v~1tgmsAJD4$054#mM*LX|5+IZ{6$pRkwss=Xu- zP(l&9A`!ac;3?^VQ+071HC&oNO$cFQ;VokTWjreFR^*bYcV483y5aQv@)huiFNps7 zN20&M{_+{Nf1*!szeB+)rSK3lm^DmgDN(qi1Q-&f`RP%%LZX}kFUmeUmQr9tPc~A( z-U{;Vt|1kBG3OI_Zt~w@~TI3JM+@L(y%?6g@44 zVrQn(uqnxu-jYBCjZsuKI+&^(eWvx-tzic@{O@o=>B1&7%ese|0zKQ{9buH2TI|8hd>fO}WrUv*D48E{&!c zN1Lhmd@Bt<(L@2S=915beDdC2O5UB7^5^DG1SmqXpKbnD^92;!rl+qcbQ2+iX}atPt|F1fi=Kja}F~ z9mg2lEXvdvyhlKRTrRvkjmoY}p|ZEx+Nk788xof7t!eMBFZ{aO~X#qQ_P75ia@?lzEMP;FXR%WE_v=K7hcYv zTZCHei1CWk#f;=QIxV~aO3<8?^vW#q9Yi`-u=Adf92=vWow%rmI98{QqbWV3PBH!=&7Q(!xa>J zw1UFWaDjNu|7acgAHliD>L}nS&P6^5Ia*E8M=B`kXelKfE2S85eielssiH{yeazuX zO6)1840uM(ksPYqmrWHNxisuR8AWtgQ83=m2TIHRnG8ZvsO2S9;&bumSnxV2uoc6F*C1wJGtM4?>&jKsEX8ucCkh zl@xrSforI&^siN< znHZY5K9l*80J5bNQm{<8{nx@5RF{AQU`oVoWk(sQcA~L&mQc{nVhZgjqA*xYM*$5- z119dtqX;|?+*LyUyKr7dso3)Kpj|kBcM-+y&ZiMwIh5R)Ls1=t6uPrWTqhj+QM(H% zrn87rcIQ#)flR78ltG1ivMCmS7ui`#p$LoKYcg)y=KHU<9}~R}FxEORPFwCUJ#n$a zl!S%0%~5mhTjSYspu3%*_+TOB9U8BHLlmMiJ0PxvXN`704C}0b`U~2&l-I_;9+tIik*_7IuMKRlR zDQIgU`NQ};Hver!6ub>Rd`BL|?#QLIj!a?k+p;NaTRw&1I$>M$DPnsbMefL_xSa)* zyC;*%yVI$Be>x@NSQNY{ba%;pulD%;rnaW8nn6aukN`rm9O)yO$9YJGE|xq_Cs_>h zl1#&0BttiA9ww4ZeC;IzTQkYf*>Vs9>7QwmXEDX^LKxdyKsnv{RC+jvs*Yt-?!G)4ifaZgPq|>LvWha% zmkbQ$X~1Iku~~?dWZxDqS>^ai7Rd_9SZOPnhC0cB;yol|A6v;P%U3c9bYOKkxPj=K z8CkfjNdMRaKv+KZfq6p>29>bq4jGIR9^-??dFQB@@4?XHRRh z+SY?Q1s0$-ejaqF3evZdLUFy&{jA8KsPNoAP0?V;pOs;#LzT91Za|^;7ywa2u}Jc4 z-~tN;6S+R0LvCwxWH=hH0T>T}QNWWF(Emz+QEivO`0XwuKS*0YzE6R?!S#vHLADy% z_}&G!zBuOB4Pa{HeLox%$JOS40Cf$n!S_5^Qga>SK4)0BfT1tx3+oHG{SN~hQ^`8d z|M3CBTlnOJr|IyUTI)s~#!<2zK(msAb9`Z19 zvkrDyHtI9fCgidzgLo^ztjX^8n3rTQo(zUP<_+0nIF#}I2?Y;dsFfKPm_jylLD?x6 zlmeEvb!wUB`R)nt5}$GM$i9NNlyiJf{Y;p1~lD zy@D{NN&Y;Rq)}zt)CHzyjBJ-0&@L_8{Sd=(hRINQ6xwlW!Y;AAQ4Qho2J$Ua`)x-@ zcDW#IIWHYa@E946HkjwL#c%~D|2|cwRmXU0>KM(C3>sJi$Wz-GmX?WQd>%Z?X+i2) zeRCr#N&0sI@+}Yh$?=z6S7(v)l99441(fBZWRH0oU{-5+izdIkqDlNkYA_}J1*XPp zG=K(Jxt5{c>8v7D-f!ud7+Pqi^8Q-@fzPTxy17G;lP4c-&0bKv?`YLn=a-a9zQ3t4x9%B?Bvy#~%m}Gkndm zeYx6oM|k?2y+HtZ0E+WNpggF=G=-(8UtTXB07iI?#04aEc>kzX@*RL5*zqHN^$a7nlLoUb{&MP!fM#|O~!bYm| zO6J4E*Mrr*##t6YSv)JGHu4@*C29IqXw zC3bL+6-6O8G{Tb0)0rZaI4@5Zd87{vdbKNFW6$8f5yLDSw7h~FpF`4{a){zY&k$Ix zF$BlS&;feFHy(M6z2skk04iT=@QkXr$raa_Xt1Q3SkjtCwC&e8?L!Wh;o80R#bJz(ew*7$kh10wg za+sPx_N{Tk@ESQU93igf{$joeWqdQtc|q!S6P2Ct)_>Rn9mSUKfjlxmc({6iC3#Ag zX-Yfv^xtz2=ddGk0&;`!mH~#)#I*=uptt`<-_qEAK!(+m`o6Gekx6P3cn9~4;O|!y9F>;@~SAaDAylm5CWDXydNDP=76AWX87RNB|#}% zym6@E(8GD4Zv=RqmaUhEP`FpyO^khAte`Q{AFxbLC?9)ss2=Y^`_@=uLpTJCWWX3H zJWdS3Y%Ucrc-j%qqe3W~Xj2j-)^q$Is|pp1LCxaaACZt1>ps9t!<>0=aRyJJ;cA&x z5a$7rm^nY7@p!mI44J4^l*guGf&wZKvNYJS@7II$j0_~Rp>9HgqH(7>Oie_HN+QQO z$!aB)C9c^AgQxBA+^@6Ee7zL@TkhFE)Ywx@!=1(L+(8e7?>lQ7e^7*w(_(o-SCu@J zf!aWTVRgiCHp-^CafL?xEpmq)$7)MXrta2a^%6IRkg8Bcw$0J&8HCgPRH4c^CoxQx zygc~G(^kcFo%78+!R-$a7LI%moD=gu!-Omr9^yB+fpD+Un34AoPUzm~sh^A0RAQD% zwHU?_V0c(#o4Tr2SKHjPofoBbaO1Nlu>Lns@D!_*tTKI(j{qrEDLJ$yoD+2mloU&2 z0fYa(vr2}+p1})DFOTP(bjrxXX256r!NwAp6MVXAkjvf>r#|BzWY-+s!gH9!5`?4j z5;t$n^q($yPL}qFEg!ec@GUlUv=E-bE0auo?F1b2L{Aw`qNl#ooa8%Vh=rvw!ruVT zP{RtsOvfe(yCeTpZO@qAdZ=u;aEPrOFb z<>{sJl7%`>{GS4(rI80%SMBC8u3>?fQ?nIhbFh#sATzB{)bY3&FUA~F8=kHy5ap3vH4KEs0dsD7 z+1cr)`v@x`EG~YqMLwC;Xk8h{x<5 zs5gv}KdiF-L_!xy9Y9=`j@m9l9fvtyw{fiD;Y$SALoSRV>*AmqA)EP^N&iJQcq;W& zZ;^aaLFe)kufMl0Z@_eZBw)u`!`~cGobwMWyUAY1G8(zX7{%o$nlLAF(y4D=lqvGp ziN^m!K8xb@=i-;M{{=R9l6r)zP#!MJN4+YR5PuIKJgpy|at|RUj+42_M=URKJyvZT z%J5nMyyC9B=KX(@WB4W0!%W=5RctQC8!ekrEve;**~ z#&cPjzMT`KMj)`qS)?e$glGH7@#DnOvA!R(`EJ)`wS}Ux(#XYX;60BY$p%kScQi*O z?O)Cf@O@$Qt zhKQR_Kc)>DAeL#$P}gU(_W1szK)CS`>W0)u)NxPaT82FXwTGzIQIVhfzPYI{!JldV z$~@7--$=n#yX}u^g9gZun(*;ZKfhui9J07d=LTf8#WIvVKs;yTkj4$g$1acWJLdP^ zBpOl|(I)B+m(s$etzMPkl`M;HLV0#Ai_-2h>=; zPtLy>_hZ_i0b&y3WN%X$n(Mixbfw!1xr>n8=en-RUf}jp{$j74<;%VI)vSaEEpS<# zwE!Vx3FPZ4#op?b&WqCKxICRX-~F}1B@QzZ+YOy9yOF8qV~sDiEY{8MoL z(}4c0%c_j$JvJ1s0rY1Td#YBuZ!B8lvLbzr=cbZXc&}xyYjYOj`8>xbhR?z0nCLJq zF~``?-bCc4AFFCto9;jC=>Efw&U8R@Ky;=9q64Bc9S|K5o#}w+Ob0{>WFLAPx_wo`adCQ3tW7zNC=gvqYj2%0Uvjmx0 zYp;9f&effn^PRo-zt25qBoUFMv%zD!M$iG#nGT2!h|Y9CbU<{b1EK?>GaV2e5M3ka zfapvILAt&)|QmPv|q%LK1PY(q?Z>>Lc8Ee!M>%_V&+ zV@coASTexh=vx@e*DyAauW4#1@2lTae4g+4upJ#GDUUTu9&Z*)dbo~hsI%m;xkU2Z zQYv|MR7gWALnVs@Ps!NJM!c_{`nx^)K=5V7aXdG4vaq&@_Z;Ea6!WBFdG>C<4dqvZ zJL*3U+t>8V@V(8yi0EwkBz#N#jiBdCdlWO%Ry!1imYMoHDD)TtH@*g{4#+w>Dm*Nd~G(3xIULg-Iz}q?=7UP zn~N#)#zGo#w*B*n7pqP>mxPZtbTqe<^z}5?)dBggKqNivqv0$Py)r#tC^#QWJ5987d8g{vzQm@RWQCDRUxqwh`{V6JbXDOAvvz*G`UD0P{?=Gj(n=7dJ z&MF$Vf6^!R=>etuetPO~r~~pK5Pi8dth4*x)8_!VPPgYa?Po5RV&#P}dO%?C1q_SJ9 zsNm)@3VJGkJCeRNzpoC+0Fzt7wl?BP|K9QU11`0Y|G9A#c)o>#0VM1~D@9(MOhbF8 zQ2eFolyq4RQ|uWU7^Uwlqbf9Z?N6Se#`o4x^UddJ?9H___SQOV*U=a}Z+h=Jz*$XI z0LC6u^5H6qey#4Dp`E#t_y9T}>Td@i_Tyt$`dtBti{r@e>^KTIKVEo82)rX4p(?7k z4WVi(CBi#~UwMK?UY&z5#W0?dVW5%O6Pn+9p2ppJfhOL1ktW@Ki6-BEnI^ygGPPoV z!mafJ5(8szVJIBJ5_XRJiLtA-rzHKm15rO5+Tz#xU2P%X3xIKM>^FKx+@)!Kc_ZVk zc}U!gsYJk7NezH8294cen1$~z zr}(axJ4Q~H9^Vy+-I!=edGs*^GNdZ3U3GOlsm_lj-?L-Lw-3m83ck<}M3Xy`)!xCO zs_^;}krOyqa7bbgXuJK2X#Dm&uhZ;1Z_=C(H^DZG{U>mYU(-NgPhrn0!gcaLSVoZ> z>n=cfne~OQZ|Ovivy&z7!wruz5WRthhgpJ;Ffr_4-W`HGrAN#-i)0%j3!CY;zwF z5wgyYL;heOa{h>hx{5kBFM+LQMzquf)z4TwpAgXFQHP*NPI zeM~|YhpL+J*}hi*<4kiO5MPalXn=^?qhDPO*9uofkhoRvt`cEqJd_kCZq668KYUYo z!&3mT^y3a%{>d(3OR&G>XC1Wkmz}iW)15T?=UZsfomYeiU@t4d^>W@`h$?>pg}q*L zNix(o(g=-%L~?)akq6TMg^WC`{k#v={m};ie9klpC=c}zEg*9KfYe3Zk&8;4 zlQ}2lrke;?x7Ujv&pm$*JYW$*)KYlGvQIi_1z@cBWH+t;)d6_TR?1#AhC<4RQ__=V zH2ymB&POka8l?=^<1ollI_2g(a;l7+_O)DshoO^&(&_04UljD@0wLYk+X=kuHE}^2alx-k5m%MG>xM-FbuNeY6GPX*)vI4uIKC zi$BKx&vsJnjydEMuD}P8`phvxLDgp#)0mIeQ3X7t0H8DBfvMMKQ$%Oe$NFZ57W$ks zw8E8XkfY?-K1_0d=@AE_se}#e%p4V+Rli{n3`BXVABqfQi~te@l{FB^bV|Ma1ZAKH z=OeU~Utdaf?>dHKoG7N2fR8}< zBxIn5Vxx4R{C(4?{?0R0gxr*c9F=-yCMCVwPWBmoHF^&K;r!v)p7iJg(R?ebOyAKQ znov}c@_6F_C@Oe~uLxVR>fIcAd!)Q493dQf-*KWQ{}Cv zC>PL20)F!K8RWM*_mCQh-s1;E{cxI-(!t@$`)Gp<<%AX#2BHpI0qQ!0W$#erk;KbW zX~g9jl!>ra0NGmsnOgtO3L5*~vrt&;5VBsT_S>)0@(;Ju@4onq?%lsjcklg`zWVB~ zbnmOb;Ujz{u*{q>RRA#t474Lzm`G%f=XMTel(DsuO5S~vGSC51E>EWDo~HjbwKsFs zR}Z-fsUG7dInI1cfIz=n;RAoFJk~(ohwDlC02J9v1}64!NZ;t*NtB328UZiKg3>C0 zmz2Xx>Jj(Hps<^Wur=j27lrF-%P)_M#{cr}U+Am5U(i=yenI!Y{0k8q9;Z*85Mhg9 zSOSK%sYFf|2IOiik-MiAW$bFCytk)O8fu`#tF2@|%&V|3uOkOqW~wBIDe;o~i+M7T zH;VhE@TOwP6HvT%mP>|CpYwts0k#|p>8j3n}oshjm)#oJu za&A0;Oh6sdN{JUHQOc#MR0J?p*j8VeO%2E;W02fi-djy=@2#b_o9k%pe|EtuzNGu` zjIaLu2fFv?-_!j+|CZ?U{}Dj8ytz?$2---%aJ4d^P#0s0^D(9bcRflRYDYN-M^i@c zM5ww6q?(t~VIA(2X&L66VV&la>o7gB*k#$M3eU}@wcdy78@xKJnyvE#TI|L|H+$`> zsPo!gS+Cez-GIbjVwLUZZ{%tv-v~1tgmsAJD4$054#mM*LX|5+IZ{6$pRkwss=Xu- zP(l&9A`!ac;3?^VQ+071HC&oNO$cFQ;VokTWjreFR^*bYcV483y5aQv@)huiFNps7 zN20&M{_+{Nf1*!szeB+)rSK3lm^DmgDN(qi1Q-&f`RP%%LZX}kFUmeUmQr9tPc~A( z-U{;Vt|1kBG3OI_Zt~w@~TI3JM+@L(y%?6g@44 zVrQn(uqnxu-jYBCjZsuKI+&^(eWvx-tzic@{O@o=>B1&7%ese|0zKQ{9buH2TI|8hd>fO}WrUv*D48E{&!c zN1Lhmd@Bt<(L@2S=915beDdC2O5UB7^5^DG1SmqXpKbnD^92;!rl+qcbQ2+iX}atPt|F1fi=Kja}F~ z9mg2lEXvdvyhlKRTrRvkjmoY}p|ZEx+Nk788xof7t!eMBFZ{aO~X#qQ_P75ia@?lzEMP;FXR%WE_v=K7hcYv zTZCHei1CWk#f;=QIxV~aO3<8?^vW#q9Yi`-u=Adf92=vWow%rmI98{QqbWV3PBH!=&7Q(!xa>J zw1UFWaDjNu|7acgAHliD>L}nS&P6^5Ia*E8M=B`kXelKfE2S85eielssiH{yeazuX zO6)1840uM(ksPYqmrWHNxisuR8AWtgQ83=m2TIHRnG8ZvsO2S9;&bumSnxV2uoc6F*C1wJGtM4?>&jKsEX8ucCkh zl@xrSforI&^siN< znHZY5K9l*80J5bNQm{<8{nx@5RF{AQU`oVoWk(sQcA~L&mQc{nVhZgjqA*xYM*$5- z119dtqX;|?+*LyUyKr7dso3)Kpj|kBcM-+y&ZiMwIh5R)Ls1=t6uPrWTqhj+QM(H% zrn87rcIQ#)flR78ltG1ivMCmS7ui`#p$LoKYcg)y=KHU<9}~R}FxEORPFwCUJ#n$a zl!S%0%~5mhTjSYspu3%*_+TOB9U8BHLlmMiJ0PxvXN`704C}0b`U~2&l-I_;9+tIik*_7IuMKRlR zDQIgU`NQ};Hver!6ub>Rd`BL|?#QLIj!a?k+p;NaTRw&1I$>M$DPnsbMefL_xSa)* zyC;*%yVI$Be>x@NSQNY{ba%;pulD%;rnaW8nn6aukN`rm9O)yO$9YJGE|xq_Cs_>h zl1#&0BttiA9ww4ZeC;IzTQkYf*>Vs9>7QwmXEDX^LKxdyKsnv{RC+jvs*Yt-?!G)4ifaZgPq|>LvWha% zmkbQ$X~1Iku~~?dWZxDqS>^ai7Rd_9SZOPnhC0cB;yol|A6v;P%U3c9bYOKkxPj=K z8CkfjNdMRaKv+KZfq6p>29>bq4jGIR9^-??dFQB@@4?XHRRh z+SY?Q1s0$-ejaqF3evZdLUFy&{jA8KsPNoAP0?V;pOs;#LzT91Za|^;7ywa2u}Jc4 z-~tN;6S+R0LvCwxWH=hH0T>T}QNWWF(Emz+QEivO`0XwuKS*0YzE6R?!S#vHLADy% z_}&G!zBuOB4Pa{HeLox%$JOS40Cf$n!S_5^Qga>SK4)0BfT1tx3+oHG{SN~hQ^`8d z|M3CBTlnOJr|IyUTI)s~#!<2zK(msAb9`Z19 zvkrDyHtI9fCgidzgLo^ztjX^8n3rTQo(zUP<_+0nIF#}I2?Y;dsFfKPm_jylLD?x6 zlmeEvb!wUB`R)nt5}$GM$i9NNlyiJf{Y;p1~lD zy@D{NN&Y;Rq)}zt)CHzyjBJ-0&@L_8{Sd=(hRINQ6xwlW!Y;AAQ4Qho2J$Ua`)x-@ zcDW#IIWHYa@E946HkjwL#c%~D|2|cwRmXU0>KM(C3>sJi$Wz-GmX?WQd>%Z?X+i2) zeRCr#N&0sI@+}Yh$?=z6S7(v)l99441(fBZWRH0oU{-5+izdIkqDlNkYA_}J1*XPp zG=K(Jxt5{c>8v7D-f!ud7+Pqi^8Q-@fzPTxy17G;lP4c-&0bKv?`YLn=a-a9zQ3t4x9%B?Bvy#~%m}Gkndm zeYx6oM|k?2y+HtZ0E+WNpggF=G=-(8UtTXB07iI?#04aEc>kzX@*RL5*zqHN^$a7nlLoUb{&MP!fM#|O~!bYm| zO6J4E*Mrr*##t6YSv)JGHu4@*C29IqXw zC3bL+6-6O8G{Tb0)0rZaI4@5Zd87{vdbKNFW6$8f5yLDSw7h~FpF`4{a){zY&k$Ix zF$BlS&;feFHy(M6z2skk04iT=@QkXr$raa_Xt1Q3SkjtCwC&e8?L!Wh;o80R#bJz(ew*7$kh10wg za+sPx_N{Tk@ESQU93igf{$joeWqdQtc|q!S6P2Ct)_>Rn9mSUKfjlxmc({6iC3#Ag zX-Yfv^xtz2=ddGk0&;`!mH~#)#I*=uptt`<-_qEAK!(+m`o6Gekx6P3cn9~4;O|!y9F>;@~SAaDAylm5CWDXydNDP=76AWX87RNB|#}% zym6@E(8GD4Zv=RqmaUhEP`FpyO^khAte`Q{AFxbLC?9)ss2=Y^`_@=uLpTJCWWX3H zJWdS3Y%Ucrc-j%qqe3W~Xj2j-)^q$Is|pp1LCxaaACZt1>ps9t!<>0=aRyJJ;cA&x z5a$7rm^nY7@p!mI44J4^l*guGf&wZKvNYJS@7II$j0_~Rp>9HgqH(7>Oie_HN+QQO z$!aB)C9c^AgQxBA+^@6Ee7zL@TkhFE)Ywx@!=1(L+(8e7?>lQ7e^7*w(_(o-SCu@J zf!aWTVRgiCHp-^CafL?xEpmq)$7)MXrta2a^%6IRkg8Bcw$0J&8HCgPRH4c^CoxQx zygc~G(^kcFo%78+!R-$a7LI%moD=gu!-Omr9^yB+fpD+Un34AoPUzm~sh^A0RAQD% zwHU?_V0c(#o4Tr2SKHjPofoBbaO1Nlu>Lns@D!_*tTKI(j{qrEDLJ$yoD+2mloU&2 z0fYa(vr2}+p1})DFOTP(bjrxXX256r!NwAp6MVXAkjvf>r#|BzWY-+s!gH9!5`?4j z5;t$n^q($yPL}qFEg!ec@GUlUv=E-bE0auo?F1b2L{Aw`qNl#ooa8%Vh=rvw!ruVT zP{RtsOvfe(yCeTpZO@qAdZ=u;aEPrOFb z<>{sJl7%`>{GS4(rI80%SMBC8u3>?fQ?nIhbFh#sATzB{)bY3&FUA~F8=kHy5ap3vH4KEs0dsD7 z+1cr)`v@x`EG~YqMLwC;Xk8h{x<5 zs5gv}KdiF-L_!xy9Y9=`j@m9l9fvtyw{fiD;Y$SALoSRV>*AmqA)EP^N&iJQcq;W& zZ;^aaLFe)kufMl0Z@_eZBw)u`!`~cGobwMWyUAY1G8(zX7{%o$nlLAF(y4D=lqvGp ziN^m!K8xb@=i-;M{{=R9l6r)zP#!MJN4+YR5PuIKJgpy|at|RUj+42_M=URKJyvZT z%J5nMyyC9B=KX(@WB4W0!%W=5RctQC8!ekrEve;**~ z#&cPjzMT`KMj)`qS)?e$glGH7@#DnOvA!R(`EJ)`wS}Ux(#XYX;60BY$p%kScQi*O z?O)Cf@O@$Qt zhKQR_Kc)>DAeL#$P}gU(_W1szK)CS`>W0)u)NxPaT82FXwTGzIQIVhfzPYI{!JldV z$~@7--$=n#yX}u^g9gZun(*;ZKfhui9J07d=LTf8#WIvVKs;yTkj4$g$1acWJLdP^ zBpOl|(I)B+m(s$etzMPkl`M;HLV0#Ai_-2h>=; zPtLy>_hZ_i0b&y3WN%X$n(Mixbfw!1xr>n8=en-RUf}jp{$j74<;%VI)vSaEEpS<# zwE!Vx3FPZ4#op?b&WqCKxICRX-~F}1B@QzZ+YOy9yOF8qV~sDiEY{8MoL z(}4c0%c_j$JvJ1s0rY1Td#YBuZ!B8lvLbzr=cbZXc&}xyYjYOj`8>xbhR?z0nCLJq zF~``?-bCc4AFFCto9;jC=>Efw&U8R@Ky;=9q64Bc9S|K5o#}w+Ob0{ahkQGh5?fG9u|DL@n;iWDGLCt)W%Q+5vag5ZEpaBJr%$;n=@cXeXfsT^^O za--)Cg1uTLIO)CAt_eX=?j7|>o+;rO9?6DukItbpG(K&^LfFC&(O9)_$NbzkS%$F9qz}aRe%t(Enm=YFAzfa z6bjx0TM6!+^@4M#7a!M7y0+#I1TU6f$G;u@-PP`$^xd`P9i|&hBV*G1w6VYJ3^00_0}^k>%p(fR>OP zI5l;>aewLWTb~~TZLdv)4%a6^$E%Z}^VKPke03_MT%88pug!#>H)lhyFXlq;TQ!hz zb1rm0HRXpkYl}V$$d4cDsCDxd?Cs?JDnMQoh+v1$vEkg4LNoMl^*ht@+=wTwua1NG zi(??6VGOi8Hx3dTCP3#46QRq+$&h;S4M@8*9nvq)gx*(XL)O)~(D&**$i7+wIX4zS z?w!SuePkH)^5a)?&!JzZAM0 z9{tcSJ*I$;XD7Ks1xRBc_F`+OGmS$ckC**5=E^8&akd&-o*5y+I6E5Jo*N4t8pew- zE>3~&m!`2*WL}vA+1F|q1T}u~&81Ls^H)&%`EnTi`3e^OU3_yH6y8_@{ckUYezz7u z%lX+mG3cx5xC#&}i7nw%(q?*e!|*3D=c^(5bQQEXQw^~Qr1jZRkZ^7cv~L&(oz72$ zxf5J)wW?Qx~lPz zgx1mZ;#BByX$HC}f-zr&fsIU-Q1QhosJi_YjJ&-TM&DTnWA3~IWA45Kqwx8N+ix=@ z0!G$CP{@UK-d**%bC6mu2>;)KNDs}}POFWVsv+tu!Z=;|OzY@)eu61(^twC?19uJN zGmIrrhA@U=S!TwA~~ zfno)@B(i|9ci!d3pK^Z_OuN4YW_-C7wT+)o#nFjOqM|n{>GP^VJ1SD{a^>o`RaX`i=yZB8of6GKSM5z+!w*5 zjEqv`ta}R}d{Ww)pRx|B{DW3x3Sqx4ZN@+qrSofBucgr83@-N=IpAgg}chd6u0QcQg%DTF_WUeP4Qydms{8x<|BZG zU+;n1hkIEI@cDw@?16>f?Snbr?uKdKY=_bJ-{mBLtSle**XPPytn%kT>rI2s3y$_q za>CKrvc3Ap3A**o9*FsZoI=#buw$ivi$DMo_2mquNei(6BE}C)b+PW~gOxZ1a|+7k zx6obPd7FDY_52xV0rSvBEkvtW^l%R>Mi`49egMn=a0IPp2V^cC25|$rLh|(fF#H4$j_zqEx~g3arsivW z{+r!UvTFwT#~biO1e3IF3{Z4x0hE9B7RM0+LiJ{{usmw#>N>gaA|CHQdf7A9yX zCkwiD%^Zka2|M_@Y7P5}{zM=MNO+wYiU?#F18Ip_mNk%x5)gAhFR=u24}qY&A|Mne zR{icU9QpGFIQ{({IQHA~kec4z3WhAtFb!lLngqoUR+@m2YwUbuDtPxY7Mp;Ob!goM zuK{srA)T8)5W!wFdC!cfq2!vdsDkiMhgd<0L@SA6w&?=8mae+B}X!a%~8_x-hC zQNpXD{SZj(YXU@i_|Hh)L+&Z;<1!J-2@5C$L~>g(QXN8RZ#ztTO+o$g3?9v;AY3e^ zyi|Ws44H)KEM-)G`QN|8V|W6Op8NjMPycTYUwZ^J(+gRl<=LwF-7qLo+&b{bfu z!Z1;)($hHYox^GBK+dvOV3D^5Mq`#m1>d&s>bT+m`S_6u2K|#Cb#--30%1$hdO+g7 zD(HH1I=ad6kZ@%@cy=-LqjUG@9xiyK8U)Y2(SqNYPJ(W2UlGXWJaa0%HBZnZl+fJ+ z1h0Zv!7WiIIO}Z~h;yWGLfEfMo?wOrVaH1)D3a?sAzDeKWF^rErA4DSk|Y&|G;BhJ z+<+Uk<~VYDEsVOm4&MCcF#P!VM~2W8kj%eOL|cFHeLvSH^*^rsq!g z9^pNF$`X3`RhaB2zlEr)Iw*^UYCs^LK|}!*`#++Aj}7+Tt<@spt&G(P>~D*8_|b zdO}onH;5S81tJO)!I0AiblsvMBrOIKj+7&i5n%kZ956P3e%Amn94NwbE)ma{-0aDr zroy&KAuQvykr1*q|CYU{itoGF3=jv6o6fho!#m;VrqHArN*Gznu~Kt9v9Jj4QLbO3y+NB+9mE#8=cjR^Hvkkc&#cGK;~H(j;YlF`tLqbMG&PoO`1B-B|?v z?$tsLZnN?I?3*=^eSHq}zAzn9uo!JsHym{D^@EU&xuD;PQ1%yz=Pg0ul>Jo2a}|Y9 ze9GI-5p2mqoPs?gvBG`dfB>kcnV?XQvvgh5^Uz9YV39_6DZ8TBL3aoV3|R<`XOYq@ z8aqvD{KgQ>nr;$*|KfBW#!tnVMD=79eF z{?<@F{b?vv1nYMc+;M5CZDUJ7qA^|EOYtLg-#`({p<>B(m9Xmy|5&_0iXk+xNU=k{ zbxSUb0FlK|EFn;xu;EBl#Z%!ZZbixOiJxmM+(*L%+}C*MKx!b3gTymqp~D%>=+2CW zj(Gg`r$<2oK2JD57Ggduhv2n+LANRQX(&HsDd@WJbN|51tJr3MI0kuyV}`Ol46Pz` z??5w@!^L8dmt7YI{iu@_5PcGZdOfDT^%&SsVYYQ@1hhI$LQtr9Y^?Y*&sJ;GcBHlV z`{KUhB*mVp7KO)(tE+<6b;D2<5c}CMh^eat<4Mf=PE~?_a~=f0-4`&`6=MnodpvJ; zx8!Q;%by7Z=^)<9zy7TgmSRR98Zpynqo-=y06Gj zF~DO`B}JVm2jhtfN!UQ2H7%o+Dy$S`dM@rSQWhR3LQ*6iHwG;=277+wM^c@HiogaB z-CYPlD>KEIvOOO=R-t(A$0c`L*L0Al`#pGlf5G%P*LJcjHz#*A+1cc#^t%zro^@uEL`hN$6C5z^LDyf0an-#IS+%{p# z19a;wt)z(0+hiq8xUQ(HBOvI_%uk$j>HwQ64Be7L3$c*GY^A>l1$&rPJUKc@ym$)y zlp0&=$P4J`Aa;LPL7R0{mXvB+$m+Wm#|o2Vd2Bi-Jz53U6{6ePD8&*wf6G`>S8lcv zsYb!`__NCBmta$AuQUO!g??N9Bf5|#p&S+)l%RxS&@^dZk@erNO8Z0^Nc%<6>s)^z z5Zyc3B9JwG*h0w42`sxbvJ5N=BO9u)NURnM!;|HY1DEwWu4-HkxN1dpQF247W`J9 z)w=aLs{?A%YBdv+YBb|I&-JNjJJWAe$JzeVQ|4(VC(rdA(cul>%J#W#$@&O;waU)H z*Nvyi+8hvR`pkw-BZ zuGMP=5X$P$?{ng@xA2K}a`Jw(Zf(HA9zw{*90AW;z(%K`Ai=F;h~OCLLF06SdzVnb zB|cDa3|8}dswh9f!N*l_4Dhf)Am*7SSu_-(+mHhxnA0$;?A8e%k_!)FZ{QiMrc9m=a_*@jeN5>@>ipL3;moB_!7Gj>cf#&azR`M+Y!63`ZXIs}3R z69lcwg5cFzA{}g143KBk%`ACr>E){U4$8qC7AW%(6<#B3jP)~j9e@52=XBd$%Wma zMl!u#EPm%ek!e4eT>Q-`MBVaPljM9#5PD#`i2QEnmj48ld zOE7OrVBYQnx^)QU-F{Z-vI)%lQh_PMAlS#Du1 zR&Gp+FAOH%TwuypBLlM101Nf!v8#ZZw9A;*y1(dR9a}z7_2R%{a0UWAg>#nPq%h*u&JhEp+IfejsaLAdR2|Gy&zQOiU^)IZfV_X9b3> zM%MOx^Eeg)A+XdDFpv*&iS-v;+XTLlXqKW^|5!oYFQ)kdaZLz%N_1iBzA=4+*JME; z#*2W(GL#;oOfIa46jw5uc3+LFec4(XgJJ6^;N*Z@BJG<1dl$EkqsGO~@nXtp!7w~C z&}F5*PC&3%dJl@9LXAqno1n0zERvyESj}bR97jxGuvZ7+dt@1$0#&=Um8)(C=jN*C~- znaca7edzJ?xV_CV$UPx(2Va4exo|F z@I45a+nx8PTbs?Uj4JhjIo)=uFi?}V{%p0-@|N$9G#4Or^TtZadch+t+!uTLe^U=9 zx5F_3V*^`@mC!X&ErKwxxBtoB!`aU&52cz$x?okbpV4PX!aq^qTh$)?#&!bjw5|{^ zKaDMgjziW%MIp^@L6}Qi&{C-a|3$)JPsj}&88r zlsa0%^Qh33jr7WI$?G|Ok&0UJVo=wPx@O|C5_MK`X&pd=i<9Wa6IIKU1yLN}z)bN0 z8!vdBC^?G?*_sEK<@9sG-l&SzntnaV&dGrn)KChFjXPd5J_%h^GH7R{NSRb`-lqu$ zP1~WHQl~0tf2s6c>e;_kWGOE30bHxtJP^9?Y$-ZXbRj2sc>;~L(!F!64Hyh%M+9f1 zDEY<}HtK(3?C>RD?Lom*r{>j5)EJzOV&>yh(e7;m;Xk_@XJzulHojlJZy*o9^K_jv z6?C8EdrT~}bPt>Y^S?sQVLp_qV0HdF1mk@PCUSJ)A-i zMku)lH5X%U$pnLZxK42I8mb9g*6Xj79PrG-9inB?UBJf61|lyGrwYA{;QmW3#8TMt z95imcoLauYWjih_LiDZFm~I_)(bzbTxN)e*(wg-;Y2Eq>adI=m`A7srpVLlCevf8< z(8aMd?t(j}nY0L##>G4`A_eb~_;k5I6i0F;7&N2Aa?UL+J3Cqa1l>v;B^SRq<$ad0 z-clL;XekE&w5`2|%7%hEx)_qZmkVWA^P(7u(i1){NW(mzoZ!{Ynt?!TST@7mN9HNE2DkX)|oMuz~ zWm`cVEd+av8#da*$cD=2F9nk!ou+K4^zZn+VD`sk9awKTWBj1uZwlxf)DcMF!k#-# zQ+a6J#wTS>FA*RMIXev0c`bQn3I8(bze%=Jsdo$G;ENS>A6nw|Q|t1qrt@O}*1pko zi&b$>Kdc-qS{J0e#Nq#1v{=z6x`H?gGJx*RQ;C$A~jy%lJuPvAms#sEROC+(1d5dF`cS- z>6q!qY+h`?lx<;AInXK4Q!MIUv1})(Yu&Jtjvhb_@Uk#W>-0V;`#}}038m@%j#>{M z@^QN!uprnZ{&q48X3661!AbTK(}&VrECU>M_PERpcTFMNBvwN)OhIX zya%@_rJhE$3|R)&9$c+sMSl8aW0NVs*H`@LmJ|~0WT2|u=atH4fOrpzACB429|#D! zEUMC}0V&&}G?XlW|0a=3qlTi_E(|xlX8d9_c$c;r%k>CmT3!Wlf@V}FtoqvvSk2$! z-*1%nL;I)~EsKvQy~aPdDIJH;MS2~fCel<<`o*|cDVqVJiu3pL8rZ6jetW@^;J5nB z!{9zMXl3S{;C0zGp}Pmvh8-HT1TAPz;PT#c(1k3(^mVD>VDXZGd1*5Omu1Y>t0~2!QL4&7y3bctb)~jqf_zo%MkjCz@@!bg>1-KiO^RV_7^SJZOmO6 zxHx^Kerx_xJl3M1)md}#?^)WZU1#8VjMPj>%5paPsW>*hs;XU*@;~e-|HFQKSG-fGARcC_oe`KolT~UWxt>UdMc^d#cu600000NkvXXu0mjf D?3XCQ literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_2.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6b490fcfcae3cf6836c56d2c4b4bb0c0487557 GIT binary patch literal 7585 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 D?3XCQ literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_3.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_3.png new file mode 100644 index 0000000000000000000000000000000000000000..dd742fc7869bda0ab6a2c229950ee0784fb790f6 GIT binary patch literal 7521 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_4.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a25d13f02a353697420f101b907ec2bcdd3e1c72 GIT binary patch literal 7937 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 aDH#or;+4PH%s;1%ru0T#?uU$N@c#gDNCid! literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_5.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_5.png new file mode 100644 index 0000000000000000000000000000000000000000..c6f991ea2bd87c11b45371a60929ebf6d1e68e00 GIT binary patch literal 7994 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�AeoQHx8U77$pgOa7ZO#RI3wu$#QRXBKD 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_6.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_6.png new file mode 100644 index 0000000000000000000000000000000000000000..52a4b8a733cb85485502b9bf689174093cbc5a85 GIT binary patch literal 8125 zcmV;uA41@XP)$#LeFOWH-5G+ugf2o149xcupUYszW1TzqGn1Psqn8OUj48$B}AZ8%uFat3IF`oo8 z5ObJ;n1PtX48#n?9A+S9Am%UwF#|D&8HhQ|K+HhQVFvP#1LXhh%L4zekTDBOIb(7Q z;Xd8U=`jV9X_U-DDd)kz6c$Wor&3t@I=HDrTqA4}eN*jH1M+MVbeWoHkDiu34nCIt zj@B|~E5=lECU>`H3P&rZaIY6X+qs*JB^47u={^t=3&_{Rcbr7%8K?r3FW73~@C zG$gXgb5hEizKe1X>sJ?EHf$`p6STJYx_D@1*6&Lnvk-KN1LkSSeH5k4iK-)V%9+f5L9 zwE@DeG(hClCWuBL1S1|{^tmw!l5S3czPG1A`fUM3?%g@i|K3~}aDN^Y+kS>7mTU3Qpb?iL-`H^1}48!F*2)R-Rp$H>_QWb|W z7UFM=H^NB0H68k)DsoT}1cD$GJy-yPTNlBQ*2OTibqNo;Kls5SD1NvI!7PRz>&jcy zfiB_vS1p7W!(2d?W7qIOug_g6J93AmcVEV-5^N zRTQ@_grRt{D;~aq09HcHqqktxqh_dkyb9_u=$0O@hM;N&KUxC)Tjzc6Ssc@7 zyg2^Rfyf=yF4}E{j{*^f{!$I-FV`4>gdz}92Lb6J0_lV5NJaxszdZx8(KGVz&4c0x z3t*~p`q7*GmR?(L5%-sJxuy|BTRm>38p;R43j_J1QS2n$iXx|Ud`1)P)I3- zA1s2*8#BJPjq*zTDNz1y6yh?j&)b1_8#oM8Afyn%Kk7v@7u3<)s1CuzDOHuAQIj`R zi!jC@jEM+hDngj?$yS*8>2{d)i4fDDY~_H)A*=?3LO)Z1KTBpm@bN-OIM(!Yg_Fkp z$3l6zfr#qRB?&U;K)-bb(@FP?BaF(ehifE z0YYWr-y-nKz9f9I{`x5JKVJp@EmaV3;dvmzA`mik@(-%6sP7;%r^s{4Nvwfc+v^R0)(*eXZv8$&-TN@r~47iK3MR@0hssY0hsyEJ7L_D^;}uxKPA|= z5agUk^B{6l*)1j)8ppqHg-}&xt8&!sDfu$sLN)lG8_@;@RieMxi9)VPKm`BDz;u<1 z>1xn}`Mk2CbVXGar65X0GchGmdYW$nWAWz);Po$#z~V0sLDk{8kUD)R~=lwgAMozo9MwPrCn^N(=;Yu1zI+R7v2a z_6iXi!m&m}r{0762R4D!3CJALKM2f%pYMbEGfN>THxBT3Aw%Th zl^6`wtt+AWNwX117M9ZKAIyf}Hw(|aR0^?>;;&6r7JP81@LZOCB>(~Vof<9xIon<( zZ9ql|DN9s{1cb&URPGjWAj>$A1`)_qH1ipsZsR_&|Env|`um^3(?5O%t-t#jj2u^Q z1YsK5%n07imp*=7Pzd@{>fIR-e|hXTmRfs#n@YNl7oy6Niy@OP{=dRIR3R?C{7zOp z^E){l{N5Yh21QI=f=b#qhLKqI_K-Z}))YR?l@v0pgF>jJr7G&y@18(sUk48!1S>16 z=b(7!M8c2{mO#P#^SMH33Xt${I=Bvr9xqfOfBA2F;eha4iysE!Ff`&7I{ALb%E9kM z1&88)x>8UHK|z&BX-fh^eF&AkG*F}}E6v2zsUZ|Rq#4G1By{DQzc>re@PGgF{h#5_ z&%T52o_!DBs0VxmVd&ike3aJbidO)D}K4Z zns$a%;rnhG_#HB0sC*BC-*)tBvR3)7Op$MDZAF@B1ht=F<=yiJ{grBVWH8zTFKctcu7Kky0b)pWs z^;(_(ltB0%DFxlpQt*|aNU4i}v+k9jKzk10>^6r}Yh)`)YK3M~!cfAJR z{`a^1K^Cc6e zbq{Ln>ONf!IU5@JiLI-zhp)f>`Z*72X=wp_d;8~MSTJMtW##Jxapy-v?5*(-b#ENl z=NQU(L4torSMhQHp`9WMInTdNb#b%(j-wJV^avs3Y%N4zY=pS0;~=u70emHuoNZG{ zyJ|}u!S^usBU5Xa|prWDzEG;d& zREKGJR`-I~2NNOk{y1jRbhM_vj1$DI4L(ePYAo<1=JegwJ zL355m)#y%^ccPNowo!_dx+Ew!OjZujQwkno*?MXcSo^#DWEif)Vtfu@94&zl-z=`34IxaOq!u3feLqgh=un@*jPmBkR&gn{6FZ9+5eO+)hQGI*?pxX@opjB4Ki3}_1_AF31wHm1hWADY>Odn;xj9wn zCGO4R8xHdB%mLqH*qfXvZ)+Asl>`{Qr2VpPl(?+hw&_9Kn?>XKhp$5N>2cr?r~9j6 z*u?ul_ys)njV1`bR11ME)evwVOYj?`z_BuBys%~HC8)9p1Xi~S{9P^8N~X5L$Fx& z+_tpaw)r6zjh;Gr2@KyJ)H)NAuTKGw!ss71@xJ~Lez5_m^avvWdm|cz zB9v#gnffAO1E2i4cu|0mlI8gOC<%nEn%OxjnU!~_eQNCP0e_C$UjRK06+zU|ArSdq zIYhVAK>XD)=pB>!hBi{iu!l<_>)K4v?k@q|AtAL1P)tTD(rDgft;8VqCt>1#tte?X z<8{GXXfcc6B;1(-iLKMY|CKC|TX$aaI+sL3#Puc!yU`woH29bQG7 zoC2Y{%fULPtpbxFAn#e}5OEKysq5$&2qOrOug4z9|EyT?ofClY<>gy-pxa&YvD{8& zL#pWZve$Gpg|00lWe^NU8|I{SWcmN~Ot&9z8|s z9JfGc%}q$@DIwlIu`P<_b6_C4NZ3}c&zOY-kSyi_9~#= zUIae75X@doUk4Bhmdd_IONGfWHI1j+)MA`@Q5AN90M+oSh*C}nMkoQo2)kV0KCYsg z?u>>o>@PxYG;k1H6&C~p=f@Xe(8VBuFvb<`CxFdve*sE2R#`HsqC($LDVfSn!|c7C zn0JJZMWzL_gsOVC&9e^mgk`%T;K~Mf`1dtxII<%E>W^hY#hF4VzEBB+u8xLcEKl>U zP65BQ`Ji2u2j1%jfcJ(1&~8RBTMNNwM<;4IDo%%`3hazDvPUo&`twyh?^9(Y1geMP zf)EBwm(qO-4iSTZauB2n^bArX!60?|<9#ypj!*~)rq!<$?lzuM3hzFJSP1ICRAudI z&)kB%m?1fYB@IoHmCafo`fscDg~Gj^&hYGA2H)XS!>OkMn_V8yt`p2-G`Vy;GSMN1E`}iGufOGit76za1wS%<>BVp08M3{Lp z3&x!-hNhdNAai`LwT3doj?h)v;J+dZeBR6f?OUjnw-L%(RLlB-pxsm;sAapT7SlAw z!Ibksr4i11CM%Fs2uN|dV~l81nE05WisAftbX@)#2&FT17~^UU!TeU!TkCHbOB&Lf70;~ItbTad3I23g2ERS3g4TV`aA#@L+XD%%bG~3|XE5{%>T0&x&mDUYQGC&Hce^b$nZ`*e#FPGBg>g}ghv*g3@KZQ$8R+qZccl(v>bhA6&SQGlY7%wb z2SiF&ZkVn@yje(kILjzcV&w;C%8&m6LHu%;2F~vGhGYAD;n;pZICQ`OI}b&|ro+9U z`D6yv4RKmBz`(K-y;)3bf%f&7m1z*PG#zxy`hoWKZ17y33!bPJ0^_|VU+@=7V_OEH zS_sTwA&n6jQVgZCc5tL97fR=jalCyPLC}Jks0`=E_)V_UlQ&EIjk}6KEQ39lW$#i) zxOW>683D0IAnx|eJxt5O`$e$KhJLK+?sE3vH+xm^V2cx+-sKJF_IShTJvunITL*Wx zdqL|KFMKQvR#jW?A0Erf^Fml|yiOJuJ2CoR*c<8Kw>TZNOZ(v;n1xVsz>}*5!ANOr z!$8sWi-a_`t34R<816IglnO&pMySHTVpiD5&Nd{}%~uvNdXISKz3KtL8|fY+ja;IR~;kXlxt zTHZt`Wcq6aZxPf|D5S9+9l-1t;T$vxBdE@UKSuBM&m z1xsKozyEAk5Mt;)522K0i4~R|rYtWOk`c!GjY?tl+iTd?v(1iQ9^a*dD_h;+m+LeF zi0u~eiygM`c$YhTw$l}UyF~-PTEc!kGo8&!31F!q4os(uax4g#oAMvp1?k{9KLb1# zWrD{N5elj0P03sGpDU4h?_vUm_b~fR0Pzq{x@kxt#OGk)@U?Z4u0n#LaIxlZqqggB z$kSh|?c7hqk%~iUWKQ>0S=fVMrDx@0!(0sR%z*tzT2&$&IVYFR+&bOv>bV_0@a0-7 z0D`f_0v>O3fn$4uVE_II*nTJ;4jhVwFITGnxGJAD_tvpK23KZqL&fPv$DQ+8mI=xmOfH)*mP&|ak`1cTw%fy6Baz`~&xLWfM z7*I#LGpin+%qrT$Qnz===XBz`GIrM~iBr3??3Jq(OzmXNoC951VBa8?IwFBp&C6$V zcQjfa`^6e-fDQQc^$ebFw1;tXl4aM9u6_y+ zTc-4~V=99SQ-`@RmEMVYt;~Iw47@8K_ZwoY9xtjww$HOw)gZ1w!i{_EyZ^*O~eD@n?O8 z#<5}3v)Ihf=CIG*z!& zXO^}qW~X&v+E^bJH!z9~8rzqRzdecFgMADht#^P8TZ3WAt{9lIKLM(bWI^$XL6CQ* z6tXUifDHUYJR_abY%G|P{D?lu#BqS(H6J{g)Q5O17NHo!L@kuU-pF}Ab&;o-D#a9x zI2$7nUI^4>Vj?&<^}^hr1a5QE_%R7E0kuxnMOy|qG8J~;Rlj{#So z_mRN+jo>sgc6xVCd#UtQ^3oU6O_&D@OE<8LVR5XqxtP8E&1&||$<016Z+j1zxVsNj z?$3aMM+QLpdqW`c>~QFFxdwWksrts&&C1VGJQgX>K0kOgr4{NsNClLpjB4o+1dN`; zM=X*uHWz|7LhzwN=T!9JH~6z_f?6ASsmmw62!}@TcoDQ{`K zmQ~S{4PTVa<}R4(ajpJ9Unt#^26+c^A?0Wh^gLM#F)dXPbGH#ZYho9P>5n#I%4iRl zO{PAVMk92Rz25H6y@Hfr1hdct$P#Y$|LHP0@rwKW^p8B2Wq*OD{}skBJ(guXb(@`b z-Ki#SgWHUhf1#A*R2vJ9BVxd56v7zW8(gO)gZtccz~>s3L9b0?6nyPF3RjJssx6tV zrOBrdsjcyM+30_E#IO9%jrbEj_e+-v35&5*R>=`u_pXPCi&Hi#X5(hd+|bVBusl6)VeEtK;{}lLZV~i2ISe8%jfBvak>9!E6=-3)RfuYSM=N?0Pa>6{ zl=G=8r*!1?Rvs^Rd4+}k!Qm_sI(fI*sh?UXWR{peqrp<#Hk^kdqx|KY_3L1aXM5J&97+ciw)vGIS!AqbSRHvj@3PwRlJw50|?>R^wTrv zhMtbr$-e$}`N4KdZ#$;xXa@LoHRpEOD-G~bef zU}4(&O6hHDjS$)|EsGzIVd?9@Z2I~okylWPGKJwuFjkqsI9$dDkK_sHJ$LMjLS^n+HAs=?u#Fn}zs34$A*ZPg@(Ox}Luv^LCw)f-ulCmS(r5DGsAl z*idn91n()Zcv!D8I5Rpfj~EXo$3KR^b0D>`)GRXF+@S6U((&_R_^^?-|Hy^yKN=;| zpa)u0Q1wLXCJJ$%maGF1`XQQ7mO$`Tv zzZ;Jz52n=G@s#z#12NekC#R7L!J(><U?vKTf7Cy^+TRh$_&DS@rV9($bSRVW@&D zRJrgKyi?+uHi5yD#^+8nj}pfol<%>LtDr7g72?8y(Aif_RYs7FFwP1v_@MA~<=0sDYUu(Y5XOjf=WnMV2roPklN4lO+`Y(nSct(o z0#RXpr$3rHVig(=cEpZ;$I5@Br;?I(eb6R`vz;uf(mDrUUM>3{RE9tG3OudQvG6!H z{Q?-4v-EKtJg}mocWfP|4xdkqHwe31XbpvqNvno@nU=2r))Js!nk>755E?}=tYmoD4KQGuNhs4_>#*h^ff3;t zqeZx-O$O))(vw0oVOm44Y)_wh$t@s)UJ^&5;TWQ43cdXDRi1WhM)XtA9KtYdc=xocV^x2Sn zOz)!MqZPV+>3}Hh)yx{@jZGE9?$#KTwy@dT5cp$(h@)>j*-tUQ+j1Zn)+xTsu8@=$ z%p9v?5@_*>uMW~ih*ND9)n7dBHNKDc52|3-08+KwPW@a^0U^VBpFRVa{{3Qn%DyOUJTDB6mmA-i z^+PaBw~V?@PuakMI9UB)yfi@Q`)WT&=1>vM?1w}!>VVrtVWn_LQMoEasN85`Yd<8s!oOvt@$*!kgJFCPG3fqPad=1@s}BtQ z7p1qIrP9Mjth&06mr5c0bJsm=dFl9EU`OpRETRB&{c`LPmZSML>-LnaqWg4<h+ewS|s_khWp3vx$yRuSdu7J6g70yQyG>_u2t(pki10Y%5yfJf?TGI?PQ* zeaH`m`M-`}{;wmL!wkd>#2jWI<}d>>12Kmgh#81E%s|XQ%wYy%24W5~5ObJ;ywLH# XOW%BAsFUR800000NkvXXu0mjf;M{q& literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_7.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_7.png new file mode 100644 index 0000000000000000000000000000000000000000..dac9338a2a478ab7c9ea419a936d6d53ad066407 GIT binary patch literal 8163 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 JPDHLkV1kd^a+Ux9 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_8.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_8.png new file mode 100644 index 0000000000000000000000000000000000000000..e3a685db113d356073ce26eeb5082a4e4537e5c8 GIT binary patch literal 8373 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 LNkvXXu0mjf#7@-@ literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Fire_9.png b/examples/moving-saw-platformer/assets/GreenHero_Fire_9.png new file mode 100644 index 0000000000000000000000000000000000000000..99a46d2f3b23401387f09e73336160db1de1eba7 GIT binary patch literal 8260 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/GreenHero_Pose2.png b/examples/moving-saw-platformer/assets/GreenHero_Pose2.png new file mode 100644 index 0000000000000000000000000000000000000000..4ccc010f3a32aa9077638a6fb887185a9286ff61 GIT binary patch literal 6428 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle41.png b/examples/moving-saw-platformer/assets/Idle41.png new file mode 100644 index 0000000000000000000000000000000000000000..1b691f09f8e4cebb198319a16d660715c8d553eb GIT binary patch literal 4379 zcmV+$5#;WPP)Mj3By{SEX z-sk&t_e{?K(wZ8aY|*J-4URKy_ou(l_c^-BOD}b9om=PDxpi)xTj$ofb#9$o=hnG( zZk?MeZ{EvCP{5&h3i&LF`jlo-*!650P?1A}$`{h$t2s3A!d!Z@IGK8E8c+Z7Fuc}A zP~hiD6k3%{Z`LoOu-Zj5pn4Gvs>-FI)k|nt^}95@W;sRFuB6ENRW#<#S{ipRpT;%j zQ$+bvdh@`{e=SJ9yJD#4jXBh-E}KGc&Z9mR^Qd1%HubMuNP})Ll$%TF?W(0TvU)ka zQ}Z5;sa;Lu>efDGFRyS;(pZx>R+?e{6+ z&inE+-kaR`K22yYqya~he|&)aPfevBb@Ql4c_#I|o=G9)45fT7^{trCP}oCmED|VC z%BY%^G^TDfMYBRCGLR_@VA`FHH2v;on$@s{W;c8wYu4Q@G=ty6-{CWH%^PV<^{O8a z9Lv>I3arYaz-#Fg#885-XHh7Fkr1lPW+)43$j!wR&QKz%S4il@)aS8E3Pc&x?-mJ& z)O*_~y>UBbG=4;xywZ84@q5V)9||BSDXxLT>&p!kuynL*1G1E*QNWE%3b>ZWU@}B4 z0Ao|j0``?fG>p|UqIwxcvZp{P2pya#PB{7AhXQ0y<4&5_w41WO+{0_Hyv}Rd#gKLg zw3)1+skb-Mq}v4)+strQx+olTSt?m7(iuvssHKMrCWO7EPdR%_rQ$6^*juy^8pob8 zq22~1rD3a_IDq7QxsP(2_tWD02Wd(3L0Zgf5&t=dAfBpUi%-a7@=z$#gBH6)@=zV7TOGFhdy(>Xt|eqkKub2nC!R zLStd`K3aPJ5Uu>`n5bku!`Se32^D^Qk_sM`(E6`Gr44^RP47KCMoS(Xq}*=~QAX1a zQ5@j zBN#5s7QV9T;m4HEN-1CvfKvF)N!t9UvsCz}(=@7J7P_bXUQDx8)cV^vJ0&3H!&7@fZ`7%|;1cXI|hARe-s{Y1is z0l{0=|FML!N{h%VJP0Riw?Z>VQR>4Tl-Rgg_KAI?6d2a<0=&j;@end|YVKZ|MBS~5 zQQ+8t;mX$E%$>)75D$K>JR(JGu@_w%KQ%4IZyJq8ta|GSIHJ!4SEz;T;9NJ-IUZG(Z50?HHv z4&lzaxAaLl(ou(7({&zA=E4lAHs#({%Hph)-L!|6vibh?@Bd3r7=|MhZ3_<%ZxxKd z8PZ)^jzKlK)UR$KnfFcV7%<*PCUHTR{&XXF8*xEHpIB{{NWhNAObDMWj z<)0e_0KhzP0Q2p)-;$e~TT3WEvHk286-)!`7E|A<911#@L>-omq<%2~MhmA9wJiv{ zk;CDXtJE^wKuSx%s!3E^g1L|O(&)We6x1h#8k?G0c+7X-eMgCjiEXMyzf7BAsPC1q%2|*@#l^*R z=FAx?Dk`GT&`?8Au)59;qdvD8O!ZvngXy+*1X-#w4TG_i*@`{A*T5LV(KFT9LJH|N zv9XAL72;+1qegOqt%b>vOInD>;S2C5%m1zdRa7BC>6|qe< zni2Psp_MxKy_qY@L0CoBtfHvewG{VY6Aj)mi+=X+zj!Vvul4n$P*!GeMHU5KO``x- z_iB->TPn%`(}!eltE%z-hh zLBj&!p0?BLiDPdF|iGe_ITN-p-MI26Dx1VQ({)Di;TShos?L#TYSOfZ+r3KR-iJ zjU61@SVBJ+4pB#-y;TKikgyPHSp91kQCQs~GJOzBzZ~d8KXZGHUhUbH{C7{Fkos)7 zD-nRP2cST)m-ymbm?{6Z?}-H0Pz(;p@AK)c!f~A2=6tkw3ONwIs&rKJP@jIR9JTRv728|bB7>eJSX$&Wk{C_t? z39Cys&#{J-RD_hSE`))Fvq`{H z7XDt+uq=jgIawK)L6r#M3pOZzzhyAj;d!af1LJ*YqOszRm+z?r@;M$yz9sSUv#5s; z)L#z>A;yx&2}$yc*t{4?itODqe z4iHSbSXEJp4HP^ACo90(TnP#ge22e_eMu&|=FsStJ5w>+8BBZT%U1~*qT8lO!ktQw zEez+wv8)~jw1X7{KzkVu{O6#eAa5NYgqe>9Ndr})1Ln9&)X(vE5T;_d*IK_|zNegY zj|t&n1PlzZ+lEop?frKYK$}M^>e;HON5V_>AFut2dc2RQ3OY7f@uA~!cA)gjSGVN7 z6Dkx2Bsc$B0fSI--w@#(Fy4C%cnrX>A-d;}B=-V_Q^;^OMpCyToqD!u>WP--4*uh< zhL`u@Ns591=wlUi3!wY#n!PVQ?*sz4%@u-c%6m4_Bq zTQyUTR!q4qIENhoK`HzmG9A7vwGw|06>zI#SG;%G$eQ=_{5@l(15xxg-_`KSz zO2f!?7QzNzhXp96FH$?`rvCC_%CL!3w=C|T(7~cp#zEqMA#Yq!DltD6dP+a)G9_5v?=mS^uC&0g0%27h7%yR^r06M945CEvWZ+#Fzois; z=eVi-oGb7xF&+Q#5WK^4DkzRonYp z>A9dN)G;U3Zk_upe=aKV@4w`V8>V$==A@KId5*$M!eOGc0aDOG0c!PY^vMcqh#|b} zfY_#k@IG7+mjr`pJR~h0uQn5bf{No+6-|~C)ULXbeM)LB){iUHc@BVFuuTKuacC%A z6HIxUZQgo*hHa9DF{gCD`ranq7#R44)@ef_=j?%4AB^N|S)h-?fqs!}1EkGkWfVEn z4wRvLmaEM3NWOY(+SGWvr_$ispM9l z7R7TrE(Zpw*y1?Eas;G7;#Z@70A<-fWZgQH4(W%UD^;J4r#5f+Yk*Wpl0klJFqHUn z*6&?SX%mVlraHs*z+k*+=t&4v%rMGQV@8SEMfTec6j2N-7FD)uDTcER8b~AeoHW_P zSlin#vYXL;Dn66JSufFb;I!HDKMf9_1QhX9C33xEdIsQ1NM*|4$~9`3D+X`)JDx;s zCb=yb(&kBYEf{I+e!0U6sGmdK3SHp$BPEqSqhdrg>>qwl2`RtgI5PSam*f2{j2vFP zVxB`SdS7U>KH3@md|*^F#%0(dsABAaMwPP?ZvT4k`(e-B{Xbh> V38`YFvta-L002ovPDHLkV1fpTPt^bb literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle42.png b/examples/moving-saw-platformer/assets/Idle42.png new file mode 100644 index 0000000000000000000000000000000000000000..1b691f09f8e4cebb198319a16d660715c8d553eb GIT binary patch literal 4379 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 V38`YFvta-L002ovPDHLkV1fpTPt^bb literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle43.png b/examples/moving-saw-platformer/assets/Idle43.png new file mode 100644 index 0000000000000000000000000000000000000000..1b691f09f8e4cebb198319a16d660715c8d553eb GIT binary patch literal 4379 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 V38`YFvta-L002ovPDHLkV1fpTPt^bb literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle44.png b/examples/moving-saw-platformer/assets/Idle44.png new file mode 100644 index 0000000000000000000000000000000000000000..0efce8793ad1770c49f119409d87caae1ea1a9dd GIT binary patch literal 4358 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle45.png b/examples/moving-saw-platformer/assets/Idle45.png new file mode 100644 index 0000000000000000000000000000000000000000..0efce8793ad1770c49f119409d87caae1ea1a9dd GIT binary patch literal 4358 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle46.png b/examples/moving-saw-platformer/assets/Idle46.png new file mode 100644 index 0000000000000000000000000000000000000000..0efce8793ad1770c49f119409d87caae1ea1a9dd GIT binary patch literal 4358 zcmV+h5&7{Mm9Y6>KNCJc_ z1jv1GBoH8o5Oa`lBZvg#P(*?tqJpld!H|QHizM8KAp6H|ty`tF|7?|RZ7IBc-}mdD zbV8CD#Yv)@u6i}Yq^GBUpZ>nHTRU~?*gCe3tz+xhI<}6jW9!&DwvMf1>)1NB-^%8( zegb)JoJgkap=8=Hk<8mBlh-R_>Hi9X!@@!2wSPMK6~t4&iewsaZV5eKol1jim($Ri zG#XyFk^*X1(&)NXG`e;bjVMc_K_Aa2pPWg*Pf#9t!PKibp8A|yM13n3k$>4DdiG2* z4J=Ec7tSuBq2)_yc=>V~S+Rm%tXxTBt5(st>U0V^mq8QjvMBg+4h5ahq#-Bf|2_b@ zY@0y6$`i@Aasm04CQ_f0B=Rp^z)%)3l*Kft3{aL)00SA#Kmr*^Q1vS`>0Bm-)MU}* znrxa|!p3UR_JWPAvTG0_ss1Lq1hW)T<<(dKV`Ml)k0&sXs$`j+HX#Y^p$k zO2$;aOygN0020ao!fJDAdfhsjS+}0T>o!pM`3*FS-_PLB@VBX#*3zU)Yshc?l-~{@ zr`#9G=Uftbm&TJ%Q5?Ha0{N9B(lZRDU+F@6j$KH(50sL|uJbahB%Oj8%GBB%S^Vtt z8)@!^%@lcY3q@Ugm7*_h<@c}BJpL@={3Zs*fa-E-%Jp?L(!#W(DSU8!K{`MrXLvmR;LR%dhXF71!USv}i}{IvKoKnuFVxL!eOM!*dfwXBmX5BFGbIZqU^oT0pY<84a+>K)3sd5|)1=JRVl zrQdjmKUZ+zVoB_B2+oK%P##i!;MGj>NFCX>aNLhfC)1f&@+vffiEaP}fwv!nK{gts z1zot&#Oe%*4~P?39MqD`YFTz|AHBqj2b3&^k$v+J<=lLiU*Dz7uktDL_94pn`w?3C zw|q*zv0K~^nF_%h#~fR|nub@UwH=r)(f!C=!D{(3lEFj@oO&>^3QS1?2i_zJyw7Rb z2*n&KThuJmIOW2Pus8%&T`h1MC}qv9cPZ!AVaomb2<6^7LhHZzke1cHK|$+dXw;er ziZ0tg3%=e>bI)(4>9xw8aO_bRR#UGXVQmA){ezjJ6348Zg$P2!?%p_Kna z&MuW~g!mG|@ddGA4hLP`jh0;9!-4iKTK&}lQA-x9B?BtCb%?TWAEvOpWO~f`Ni10G zPu;sv$a_mE?)FY82ysjtJD_p}4L-NLZNR{VJPYP&iczlQ)eM+^rOkk;T_@QHU>0(w zLC}3k0|VQ9`xqViM-d(WS0zPca~tqLCkqta9)A2$3doD5h?`rb9uhE|^@g5bL0;Us zw{m)(NT!ll4aU7@WTbhBWfAQX9ex<*!dPOD*X zH3PN64yhXH7HL2%)Hf@Xg06Bs!@q$- zazJe>*EQzK_~xNlRHHJJ6nNYxp^ibi9$vAW##C`uVlc=gvnBX$mBJ2L397mM{XYpP ze!TmW1ihutt_`74m(!(tf3|iBxvpuYp_gOMiz*vg0b{bb6K5tZ z0P6*ws$=S_USl1Ta(xf|^}pX*6w?^WojZ5P-`~G!Fi_4T50UTd)98h|<_yTXic_^8W3v|ZtbK#F{5R1 zv*$$6^&8hMYWeQF?`X%49rVN#Pc*9*qd7zlAphDF>V3AA0DDZcYmZ(=*kJs8@9>j6)qW zN0TjqSL{obwkmKH&q&B%CD1!5F@0s3gODxHEc<2}EIx(E9GVkii{ z=6%zsPvt`DSr|*+TYU)B?EG80)w@ z97vrXeYi;|e-88}KTgZN&m=OGSOukkRr}doQLg*(aQlIAS{F#B3fsVVd^(3b{t}^7 z!&gm>CK`?<0LMpzBkIurA#1_KaHkTW;A#Uame30q(#ZGl9D011XG5g~_a?vc`P8dS zgTm@Gu?xvX`Ba?)6l^yzuKPJ7or$px%qO$S<72i@TZV&ymhM_e=g3-65L^uX6+juS zA6K%dW=*@NlGC!`A zi{t)Lxcsi^Y^?pjAb?rzk%~~iM3UQk)5-n)84PHq_;*9~sJJ5;3q>HTP#G48Yy#`a zZqdLBmFa(%RLtKMAW#WZ$xu9WDEzzleM}bt#${88ec;HHt|;0%7+$z*ei*sEJ52#P zHd7Sj0YH4ho*aJ!5Uwn;hGr(d+PaxfMKx~)QI`Fn5HAe~jw!JXZVV{=yB;UP<($k_ z@$_`+U^{_9VP_2t?*rFyeQPqgzB5$;I@|;xCK`{26_8o=ESg~?|P+`dG)c$>|60mfx- z2sv&HBxk^REl2}2NdelcD~JIdFaSENAc>L$l);Y8Y}o|J4E6m(>UeTX$LRJNq_zXY zCxBZkj_byd6L+*uTgE9s+k@nD0km5O#P0RB2IwH$Ap<0KM_H%_t3|^;_zr&`pp7nM z%$5iRzy1>qD@IuFlW>K&HgRILIOdF2a5jupfL>)l+gLr@Sv`3SXcqu6oV}ssf(#}K z(%kHzrX(GdHPe9LyKtB0#v-_|ZKD{zN=Ts&48mNwn5|$qWQ|g`#sFvI zSW%9^+13b-t{%9T0Mgw|S5jkGN>%s{)F+B5Y~coAMZCQf(=r(JQSf=da0HCCV?;4f zjs?zo9S&!$#>&xBdqedoIAZ%XCFyEnWeHF=?2GERSyw{vJ!7Xv5|Q78JCKDPax1a4L%?SBgei;)KrIpzR} z+fg-7?YeBJ)D&2RT=g9WKEu^<}In7V~XCSO1kEP5G?{g>F4OYHHh5ur}1Y~s9Q=v+dhwntb;2jX%ts`p8*iu zg=2~YUfvIid2*h=)f1M~t|>|aGk_rIqQ=oXb_}C9zMv@V)E>8P=_6!}AWa;{BdI-f zcR=QVtH90R3jDrny7emw6(QIvAX?#fL~B50LO5H^bqnU%ci??Ln*+-qwS@3*>}x;yR!L10-!|jeTqi=*x%7F&nx~WYa}vdj)e( z)!7)34oO>}tt9|@F#Ud1vryVI7*k0zPeK$nge3R2*)?o(rS0R@G4+S6TWS*RHE(H^ znQ)u|XAB*$`$6j+FaFE9pL<-_y`k*`j;+uB-m?f^G#bfY6O0^}J8VZTINQF4!43bC zpAQBwk>>CF?nHYH#*%_68%X|Ee7W3K^jAQ0V z>W+!rYuxnVrat#gZbxRwJ#4v4m>j8E zkld@nP#vGijr`->hv5bsZujO-rS7}$@Bbk3Kb^JxlP>GpRsaA107*qoM6N<$g23%A Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle47.png b/examples/moving-saw-platformer/assets/Idle47.png new file mode 100644 index 0000000000000000000000000000000000000000..d30df15395ed0b1c700fa27f9ae1ce1d45dc732f GIT binary patch literal 4382 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 Y0v1O<6QEy&IsgCw07*qoM6N<$g03k^$p8QV literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle48.png b/examples/moving-saw-platformer/assets/Idle48.png new file mode 100644 index 0000000000000000000000000000000000000000..d30df15395ed0b1c700fa27f9ae1ce1d45dc732f GIT binary patch literal 4382 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 Y0v1O<6QEy&IsgCw07*qoM6N<$g03k^$p8QV literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle49.png b/examples/moving-saw-platformer/assets/Idle49.png new file mode 100644 index 0000000000000000000000000000000000000000..058c15d2b1c9a5bf43c4de2228452e8f92c26320 GIT binary patch literal 4452 zcmV-q5u5IbP)Gx zD)JOjL9xsisi>&=$k3EBpPBe7E7MBlCCD2RMboU^nVo58nw{Bpwwaxs-Rif$@9&&* z@41)Pb-U_qhr|5mUM}~Zd;XvE{e6GG|L+`r^{ei!d+Xl1x9+Wb>)yJz?yY<4-nzH$ zt$XX&8&850faQdOr25&!PTxizvKi5e=wbOoMB3X;{rm6j8gBM%FE-F%2szswt16Th`FH zYintA%?b)Xoc#X<$xs+e!I$Pz-?{}9Qk6x|UYbv#mljZ1WeyFfVknoF&>yN_q7gMO z)9Bh26jis1qU&Fw@%5`IwqXrTXjn@Vn|NH^KohQSponuhzidEm%OfbTJe`7TvnaTN z!IWpxGncZcpFqi`fed8`Ly4$nmDDb$$hws@j)6>I7?T?FDWPdSO=;RdQ=1BCYIA`+ z$7}H|1r&FqfCd(4{PF<#9-mIV>gG{UMFs_z&!s*L=9!9l^c<@tta2eMWsyLEQbsY9 zsQOhjzF{@RF_6g&V0!aLO8op)nswz>ntf#pkF7N8^DXoOzc#&jle{OPbt6SL#1yu4VOJy(| zMhvDmLddL^Y*EWlR?Beqlt}iJn0gBoOn6SqHUW}(bth$AdxI9V?&h&a9<#3PVn~Go z4GNmtv{61g@g~FB-E{{e0`$C44d2OetXQsd@kPwV%&8MI>wDPc53Qwy6dGEYL|dP;2GEFpq$na@yi7{C$+vh<66 zwCv^qTJgmJTE=7PjeYWZwhAYuWxD`{=OBYcU(a_QFy6f7-t+|k=n9@=5eUxuu@*+$uIk2KdroZi1Kb7rdMvg zBabU@9+cMsXCa3c)Rn|QVb)O1xW-p#WaEna59jG+!^ppGF8P%tcK`;)Yw?#smz6LY z&0!S7sX3ngVFqUzs0EXRkL2EXi(XcttY#ogW4sW3%bFajfQjGGKRwl(nknjQZQ3d z%XO&bZCcKghf4Ap#`@dEwBhzKTK8o!<$uM`zd1?EZyluEn|o>TANNtlwL($c6jokr z{Tep(l{E5N9vRXG-XAz_1!Krml}3IS=MX#waP(k;^kCF9Jy`XZCIU;xDTLXr#xPRF67fr0Uk5HPC0aEeCF0@Kxp(JJ;637cDr$E^EP zF{OUAo_aj%gUMPA|0x40=_=PYty^WE*mp$DQX1N_?B0Xvxn!_pA>RuM5G|DOXluS& zC<&Nq1vYm92P;UNLG$k~9r4*WZ$i zwE63k^p}7Ajcm6ce)xgX)6?69^F**aMO|1*<9J0L!3Gbb5365vZ^4+V(iPJ!?RW&J zO9CxjhgD_EQUGT&QZ-)~=1ewUr0Oiyd{M+T{r$Fp`1gg%Dn+&k6JV^+6o(O2P_M;A`d;7F}#2r zuc~GSF9}e=&bz&bqKY!f%j82_JJu$Zkx7kvJ*^rg09d@zOjSchXl&R9)9EznmKDG6%`fHp+lUu^YX~g&#zOZ z=!eVX5PG&Tn|jyW12D#qULaFN*I^_zO^M<&TCvwh^_oz%Q6+1pS|y~U*lXTEiLG16 zCCt|@MRYbEc<|R`+7nNGYqBV)YAzXyV(%^-ZL!$Z@I}GLHI7LIgOCbVGnDPR3GD~K ziEUU-ldo>1k;mrKLr*;Vv%t8fgwrz(*%ZXz8^Av2b8On(1LKxAiu`Nr^A|wzJ)fi$ ze5KZva9`b`av;MQ%F01ljo~%UI0h7dVDttCuQH{A8PE*pi&5C=V+R;OOgV2I0$F{Dghz}Ri5m8Z0vPMr?+oDo1OQhpYWyRL59s4&{0$qG1^g|9k}n ztQt!Xxjfdf+5YxH^4SzkA&m^BES&;M7z);LpC-vkGF?t1_rhq$gXx+32mAbm!Qc!b zdl}Epv{sF7ff;BHE5(qtW;p;Myuzz;1QLe$5U-R&KhB^Y<9oMN%A*gF&#U7oq-mkF zQv*s<$#hW(AwV&nWiYICpVNts2V;11lHLAdJi}19Iu_N~hE$2AEuk5*^o7NgGtCOp zAYmZXkmAE?dF|7br;+FO z33TrZJ3cE=hu1p^{Q2`L5U3KK^05VqfYFvHY`})M90=yAlzw)#8K5ZR`-$YWFOIwp#go^O$>d$E z0y@zo~CQ4;cBVFz<3tMkX@m~ac_y{9NiCWrBXWf(gd@}AR*m&ks2e*&NPZ7w+VT}94J9Sq9j z_XP!YSX!uaaZIX4Vb{eK0lWwP;<|PuxfP5iw~b@00D0_SK!vQJT?}VWEP2A9`TYQ7 z&;#PLZH9zVtRGV?;Eq{f$ot+^{7ay8)ueY+q1Uy)B#ZmIZyhUOT=Pef+xk(~fVMKA z?F?s!F1!Q~tLN=Fi-HcuD@OfJf)yzJ@YW4^P4z5%kAW50)$yYAa7^>Ni;M)dcpsZa zF3F+f!IKv_Yetakx=|8ZxW?_KSI=vjdJtZ*mhcillN1F3&>O7fxUL>yt)5Lba9-EoXy%OYvH_%rq#ppK zK6>+j;w;zHlR90#NCjNzfF7`a7gq%!&8J^f?wo{|Kp{{Lq%F#U?{oyGPzOiz9!)(M z`zI+wgQSNAIQ$%+foja10MuPo9Un8Ua<~>mIzTbFD$v<=YF*4CG%#tv0T_4+K)B{J z9E6tMl(%c99HW?WM{xGp0D@BZ5f!$CA^#nj3F<^oESEdQ%rxq8ufA37oel%KHG%>wuEY zP{-i8<@#47`8Q-*XH$Oe-!PYail;knS>Vbh3J6GbSZ~1jK_1z_s&B(t0u#aH5F(hk zK-i?H#}mqUBUUD+RL8NF;%~1~-x&0s!jqNP)P2hP0d2ps%rLLwx$^ZrXT3l)@cwbU zP_(k7Ng>bI$KRd4FV3!%^#|I&;TV;uWC@;}c`^(GpMyd)e=%^HM%Kb-o=gj)r{)i! zr&mUhOYUHLa!#n_%x@X112R!e8Q(AIT3eK!R#xn2emU(8&^SQv6PD6k03pM$BCu|P zkBHfF*Z@RV`*WH9yzIxIE<^>$F%8HJT@!4!RNtQ4qn#5DI&`wIlU43?r8<3ADb*1g z;uHH+L)~Lv(?~#TA#-Y)4G>*dkP`&H$0@;}^b66|+0W`M~seX{dG6ygfkbfFIahBJi@o z53P?*pqRUJTb)obDB7?Sp6WH&=SP)0_*A9DG@_eRo{J6KXQZ zU`O3y@9ndCuR&NlPe!uyHdou#d5`SQ|9u8E&z*pgyV7}O?Yd!<6Z}KhstEh<&$E%f zv5WgwBu$s6+}Xa%6h+>5Fj)K8>jQV%wQo1m*#lidYQp`61H+TPN2Sv36Y1ko`(5h- zRw&Q4zss5B&!OAj(Y^zk=SdlW&uIIRo{%=Qedz`+5CS*~%llu)paHcbnvCyFlQV^T zYu$IokP#Qp4o~Kg;dN3mI{LWqA4lH2X7b~u!X4ef#3g}|7o+az5TXgTJ(>)=Cnz^6 qeZcE6tis>pb=Z*vX?^~j`TQ4pwnGV2RO=A{0000Gx zD)JOjL9xsisi>&=$k3EBpPBe7E7MBlCCD2RMboU^nVo58nw{Bpwwaxs-Rif$@9&&* z@41)Pb-U_qhr|5mUM}~Zd;XvE{e6GG|L+`r^{ei!d+Xl1x9+Wb>)yJz?yY<4-nzH$ zt$XX&8&850faQdOr25&!PTxizvKi5e=wbOoMB3X;{rm6j8gBM%FE-F%2szswt16Th`FH zYintA%?b)Xoc#X<$xs+e!I$Pz-?{}9Qk6x|UYbv#mljZ1WeyFfVknoF&>yN_q7gMO z)9Bh26jis1qU&Fw@%5`IwqXrTXjn@Vn|NH^KohQSponuhzidEm%OfbTJe`7TvnaTN z!IWpxGncZcpFqi`fed8`Ly4$nmDDb$$hws@j)6>I7?T?FDWPdSO=;RdQ=1BCYIA`+ z$7}H|1r&FqfCd(4{PF<#9-mIV>gG{UMFs_z&!s*L=9!9l^c<@tta2eMWsyLEQbsY9 zsQOhjzF{@RF_6g&V0!aLO8op)nswz>ntf#pkF7N8^DXoOzc#&jle{OPbt6SL#1yu4VOJy(| zMhvDmLddL^Y*EWlR?Beqlt}iJn0gBoOn6SqHUW}(bth$AdxI9V?&h&a9<#3PVn~Go z4GNmtv{61g@g~FB-E{{e0`$C44d2OetXQsd@kPwV%&8MI>wDPc53Qwy6dGEYL|dP;2GEFpq$na@yi7{C$+vh<66 zwCv^qTJgmJTE=7PjeYWZwhAYuWxD`{=OBYcU(a_QFy6f7-t+|k=n9@=5eUxuu@*+$uIk2KdroZi1Kb7rdMvg zBabU@9+cMsXCa3c)Rn|QVb)O1xW-p#WaEna59jG+!^ppGF8P%tcK`;)Yw?#smz6LY z&0!S7sX3ngVFqUzs0EXRkL2EXi(XcttY#ogW4sW3%bFajfQjGGKRwl(nknjQZQ3d z%XO&bZCcKghf4Ap#`@dEwBhzKTK8o!<$uM`zd1?EZyluEn|o>TANNtlwL($c6jokr z{Tep(l{E5N9vRXG-XAz_1!Krml}3IS=MX#waP(k;^kCF9Jy`XZCIU;xDTLXr#xPRF67fr0Uk5HPC0aEeCF0@Kxp(JJ;637cDr$E^EP zF{OUAo_aj%gUMPA|0x40=_=PYty^WE*mp$DQX1N_?B0Xvxn!_pA>RuM5G|DOXluS& zC<&Nq1vYm92P;UNLG$k~9r4*WZ$i zwE63k^p}7Ajcm6ce)xgX)6?69^F**aMO|1*<9J0L!3Gbb5365vZ^4+V(iPJ!?RW&J zO9CxjhgD_EQUGT&QZ-)~=1ewUr0Oiyd{M+T{r$Fp`1gg%Dn+&k6JV^+6o(O2P_M;A`d;7F}#2r zuc~GSF9}e=&bz&bqKY!f%j82_JJu$Zkx7kvJ*^rg09d@zOjSchXl&R9)9EznmKDG6%`fHp+lUu^YX~g&#zOZ z=!eVX5PG&Tn|jyW12D#qULaFN*I^_zO^M<&TCvwh^_oz%Q6+1pS|y~U*lXTEiLG16 zCCt|@MRYbEc<|R`+7nNGYqBV)YAzXyV(%^-ZL!$Z@I}GLHI7LIgOCbVGnDPR3GD~K ziEUU-ldo>1k;mrKLr*;Vv%t8fgwrz(*%ZXz8^Av2b8On(1LKxAiu`Nr^A|wzJ)fi$ ze5KZva9`b`av;MQ%F01ljo~%UI0h7dVDttCuQH{A8PE*pi&5C=V+R;OOgV2I0$F{Dghz}Ri5m8Z0vPMr?+oDo1OQhpYWyRL59s4&{0$qG1^g|9k}n ztQt!Xxjfdf+5YxH^4SzkA&m^BES&;M7z);LpC-vkGF?t1_rhq$gXx+32mAbm!Qc!b zdl}Epv{sF7ff;BHE5(qtW;p;Myuzz;1QLe$5U-R&KhB^Y<9oMN%A*gF&#U7oq-mkF zQv*s<$#hW(AwV&nWiYICpVNts2V;11lHLAdJi}19Iu_N~hE$2AEuk5*^o7NgGtCOp zAYmZXkmAE?dF|7br;+FO z33TrZJ3cE=hu1p^{Q2`L5U3KK^05VqfYFvHY`})M90=yAlzw)#8K5ZR`-$YWFOIwp#go^O$>d$E z0y@zo~CQ4;cBVFz<3tMkX@m~ac_y{9NiCWrBXWf(gd@}AR*m&ks2e*&NPZ7w+VT}94J9Sq9j z_XP!YSX!uaaZIX4Vb{eK0lWwP;<|PuxfP5iw~b@00D0_SK!vQJT?}VWEP2A9`TYQ7 z&;#PLZH9zVtRGV?;Eq{f$ot+^{7ay8)ueY+q1Uy)B#ZmIZyhUOT=Pef+xk(~fVMKA z?F?s!F1!Q~tLN=Fi-HcuD@OfJf)yzJ@YW4^P4z5%kAW50)$yYAa7^>Ni;M)dcpsZa zF3F+f!IKv_Yetakx=|8ZxW?_KSI=vjdJtZ*mhcillN1F3&>O7fxUL>yt)5Lba9-EoXy%OYvH_%rq#ppK zK6>+j;w;zHlR90#NCjNzfF7`a7gq%!&8J^f?wo{|Kp{{Lq%F#U?{oyGPzOiz9!)(M z`zI+wgQSNAIQ$%+foja10MuPo9Un8Ua<~>mIzTbFD$v<=YF*4CG%#tv0T_4+K)B{J z9E6tMl(%c99HW?WM{xGp0D@BZ5f!$CA^#nj3F<^oESEdQ%rxq8ufA37oel%KHG%>wuEY zP{-i8<@#47`8Q-*XH$Oe-!PYail;knS>Vbh3J6GbSZ~1jK_1z_s&B(t0u#aH5F(hk zK-i?H#}mqUBUUD+RL8NF;%~1~-x&0s!jqNP)P2hP0d2ps%rLLwx$^ZrXT3l)@cwbU zP_(k7Ng>bI$KRd4FV3!%^#|I&;TV;uWC@;}c`^(GpMyd)e=%^HM%Kb-o=gj)r{)i! zr&mUhOYUHLa!#n_%x@X112R!e8Q(AIT3eK!R#xn2emU(8&^SQv6PD6k03pM$BCu|P zkBHfF*Z@RV`*WH9yzIxIE<^>$F%8HJT@!4!RNtQ4qn#5DI&`wIlU43?r8<3ADb*1g z;uHH+L)~Lv(?~#TA#-Y)4G>*dkP`&H$0@;}^b66|+0W`M~seX{dG6ygfkbfFIahBJi@o z53P?*pqRUJTb)obDB7?Sp6WH&=SP)0_*A9DG@_eRo{J6KXQZ zU`O3y@9ndCuR&NlPe!uyHdou#d5`SQ|9u8E&z*pgyV7}O?Yd!<6Z}KhstEh<&$E%f zv5WgwBu$s6+}Xa%6h+>5Fj)K8>jQV%wQo1m*#lidYQp`61H+TPN2Sv36Y1ko`(5h- zRw&Q4zss5B&!OAj(Y^zk=SdlW&uIIRo{%=Qedz`+5CS*~%llu)paHcbnvCyFlQV^T zYu$IokP#Qp4o~Kg;dN3mI{LWqA4lH2X7b~u!X4ef#3g}|7o+az5TXgTJ(>)=Cnz^6 qeZcE6tis>pb=Z*vX?^~j`TQ4pwnGV2RO=A{0000cQCZU6~z^o#F#{BVziA*(Clg^Q4H{=YG%kEcf|~U-WPNTmRO-^>6)K|JJ|tZ~a^U*1z>{ z{agR`kZz6{{^U^@MBc?=jUZk4Ghz(^T_9X0*$Q6 zrZEjK(zu3Pnoyrh{`ISAN_`$pZCFdwudk0f!wY{$@^g4?$&DQpdbf}!eVG36z;QdVl)UTGXzJ`80T)KZ=HSeSN=2t0!7amvgbIWh+mG^|Pl0t8BcvY|K z`*1wYMAP7!6!I!fpur5qmRb-(ldFD9)2j1mR?RvJ(x5Em6OFvFn^rWvED(~ve2r3X zzCr0X4^sNAgYuaA+bOttOW%d#elCW*s*^P+3FIwmN!GlD z)l!kk-jYrJtdOwA1IO`|xn!I4;h^$tItq)qpZ%kxlD zPD`<@5a$_EM?n`?Y z&Y(jfq7L0#j0?{zFo}|t6qpPeSE+f7K`{{m#-JF3@m~9nJM_bkKaz2~ckdnzA3oeB z9QS1tY4OdSG`AsNibwzITpC@O)w^IkE-?gFhBcH{IB{I$C0f$8WTnb%4NRWFV^pe6 z)I0_?3Vi1LU+V?L|NQt5`Ufun!hhIWT3YDIC!e$l#}qk%<~A45w3()zm~2oS&7Zpn3b|vHLJOX`O|;@O+Y9xKhO`bqEF_)y8MUfLBTLh;|^TE?-6qs*X`U zlg@QX)}3Oy`Cs1(0D)pq3%2jS|DH@H)BR8$F(@Z{8cl3mO(UzbXvo>v-T~uT#&t_+ zoLyi#3a14ePGO>&JzU=JqqMt46n1tU%?u5qzy1C1WNXXM&u>>Pmi5a=XmHUI8d;Z3 zLo3sI9*o208Dviw=|0mYZL?}dYu&Xpku_^&N*B_gvJ<=}>D~eITr^HjZtxIqDk&+U zZ@>MPzWeSws;{r7h=_=ep=j&b&|x&9A%}cxdtqkd_Wm+X(+T#0xfG{$+KDoLkY-YA z4g4*wfttlE;*g4HETot(_tI~C2DUlDC!TnMo_gvjyMgG-dChe4tIZ^z+BAAD$G>Oc zcvdIb1x3<07k%a{wrd&;tBmb|g2U;%We<(sytva4tk=IzaHZju>Eu(EOoJsNp zdk&1#_SrI8unP=BasND)3%)o@?<5(DLke@>(dDfz0&0$#+*G2rf#)o}y^DOa0)H}; zUp@OTF)>!&i=4zt| zHRcSeXWwbrL4E}x^vGk6b`A`iu4(T)@~h`;bS06z0EMe_T+p5iqsm0P!^r*oa&8w^ zNFODtv4&%q>W!;Z;|R11Q?)w=;yo=}Y5dWZ^v}-r`-@Y~6!L4xCZEzI@?y1ke!<6c zeg)y!on8s*emD*Vv+N5ar18&JlIc@!FfXi7$`Lrm9;!8kE9Gc+4mh-6%4js9ps5J4 z=6srTK9dH_8q#qV3iqSoFk3DtC4>M4z1(NZS?LMn`d&o$gMoS3r5Fa|{^@cueG)AP zq{Bf-wSi+%j!NUGjMYpyOL{8(MjYnDQ|e!$Dc9GK*N*x0nDcLJLK(1Z1P!mrAfIxE zas|GkE|5E`1s6%OBp-jT_eRDrGM$Z53u6gGNJ;l?7)uP+4B1z^yN1uLNfc*0DUy)A4ihuTy%$U^huw7n+4u8i~#`>?n8|*E)Kg9RhcxBi?$(W`NWGBk+~$2 ze6OXGcNu$%6%;5I#~`7^--kA4(4lVZo1V{`YNx-%a|p$d>*;U>=c7oa9DdF^tYoOA zn=)F5D=NI?23;vbDovKuZoNZVC)&al z@9e_o&b5Y)K;iE(eH3+nCS^#t-P85{XvZwOjTayWz8XXW0q5X+!a&RUO#>i3#NIIg z(p7{L(m|c=+_C_{et3USitDMRYDjNG>A28cpVk#G?08yNs+z`uug@c=y>rNEAH&%n zB>!&{kftCP0OAvn6VV|do8bgMj8rFU&%*mZh>(2%ILsfw+Ve$obrL!65AGTqcb2M5 z>^cY|NZGM4keqhUR&ZXPs{p+g+^QfBG2C6aFT`{}P>~Kv2W8KCuT>@R4}AWCb0YZ6 zsqn6W5$YWnFTlCJ8$piSW|AX^o&eg#fc7w;SLUkl(g76#&_V_12m?B5P!Q5QAmQXr zg{yVi#(LMVP8)#mBUFe?_rNN>JL(y!UpfL)p?Z)3FHR!I?K9QV0qF{2Ku!SkdN4U3 zFof4z20-wjV@oWMETD8)?Ja)Yg&$o`gvoK>B6Jk~=4(k^17q%JVuv(+zV#k405}v( zCx@*w$iWC`4+DBx_n%-ZgATC(a?wp1Dmtz~vR)?*OP&k6FEq@x4^9~9n+9Z!|LJf# zO4ZVT9B%!|1xyzzaoEgowlJJ+w$-D|nE?S#(Sp|Sg8v*@tUTzb0n#x|O*$}r=?Xj6 z_9w0qN)ISXQJX=z-SXQPo8(bRuASOOF#>@7#c}IQr5;;w_RVe0TnAd=Nd5Dc4oI1_ zgqc9nKm>vT`?xSAk6 z*7Gj~bYF)(V3ofd40h~#DuSNPoM?0BxRN+nTv?omTzysoR3Raz)irn?Mc~u1BY0mE z=()TXRLE@(paHp)>DlD5^i=pz0f>ECR0JT$P!y_)8I`gLV-4Ux*{shSc(8C|Yud+Y~A3;`Xl zrJ+M*iURDon$rx@LxQh7Alb7|sc=g)g#d_525pZ`p`1Pm#+hZ0gH*GTDAh4rb-ewOXoG6Yg0uB6O$FQ|!}Wy+?5VkmCs?2|oid3d7rFwTmNK=j4m3-Ems zjOxbY)q!7H*$U{Q0TRN1pL6MiQKEylsgf%_Ft+TG``gB@76)$)NLv^$qM@`KIDUQp z04NqPCm#kd)_^of9+zUJ;Og}F<8oZPQ1n}{sCoJv6m-iSjzP7P>ns?%=FY4tWWByu z+#R*^#+)|wGkt8IQ9i#h!0sO`dBT9-kLX))O!mx&tvYk-If~5^fXjdQhyD9aBA2%o zQ6KUb`wzY|w=z)o$Upt*#D2ZF>BX3%Pk=Go`@=<}^ve^Z34Gw4ii>vMBDT7v(=GRp zx@^1{K>q|V`hA}6R-!=X{SGW%`18U+AA|w4{00~^oALz9>_#5T)FY}>{H?#PUs>Gt zXm8(MjcJm_@ELtS@Ept1_hncxVF2$Fy_5671?0@iL0OLZ3I1iR(;M^D4YA{4+z4`? zbPAnzn2aG@FcQCZU6~z^o#F#{BVziA*(Clg^Q4H{=YG%kEcf|~U-WPNTmRO-^>6)K|JJ|tZ~a^U*1z>{ z{agR`kZz6{{^U^@MBc?=jUZk4Ghz(^T_9X0*$Q6 zrZEjK(zu3Pnoyrh{`ISAN_`$pZCFdwudk0f!wY{$@^g4?$&DQpdbf}!eVG36z;QdVl)UTGXzJ`80T)KZ=HSeSN=2t0!7amvgbIWh+mG^|Pl0t8BcvY|K z`*1wYMAP7!6!I!fpur5qmRb-(ldFD9)2j1mR?RvJ(x5Em6OFvFn^rWvED(~ve2r3X zzCr0X4^sNAgYuaA+bOttOW%d#elCW*s*^P+3FIwmN!GlD z)l!kk-jYrJtdOwA1IO`|xn!I4;h^$tItq)qpZ%kxlD zPD`<@5a$_EM?n`?Y z&Y(jfq7L0#j0?{zFo}|t6qpPeSE+f7K`{{m#-JF3@m~9nJM_bkKaz2~ckdnzA3oeB z9QS1tY4OdSG`AsNibwzITpC@O)w^IkE-?gFhBcH{IB{I$C0f$8WTnb%4NRWFV^pe6 z)I0_?3Vi1LU+V?L|NQt5`Ufun!hhIWT3YDIC!e$l#}qk%<~A45w3()zm~2oS&7Zpn3b|vHLJOX`O|;@O+Y9xKhO`bqEF_)y8MUfLBTLh;|^TE?-6qs*X`U zlg@QX)}3Oy`Cs1(0D)pq3%2jS|DH@H)BR8$F(@Z{8cl3mO(UzbXvo>v-T~uT#&t_+ zoLyi#3a14ePGO>&JzU=JqqMt46n1tU%?u5qzy1C1WNXXM&u>>Pmi5a=XmHUI8d;Z3 zLo3sI9*o208Dviw=|0mYZL?}dYu&Xpku_^&N*B_gvJ<=}>D~eITr^HjZtxIqDk&+U zZ@>MPzWeSws;{r7h=_=ep=j&b&|x&9A%}cxdtqkd_Wm+X(+T#0xfG{$+KDoLkY-YA z4g4*wfttlE;*g4HETot(_tI~C2DUlDC!TnMo_gvjyMgG-dChe4tIZ^z+BAAD$G>Oc zcvdIb1x3<07k%a{wrd&;tBmb|g2U;%We<(sytva4tk=IzaHZju>Eu(EOoJsNp zdk&1#_SrI8unP=BasND)3%)o@?<5(DLke@>(dDfz0&0$#+*G2rf#)o}y^DOa0)H}; zUp@OTF)>!&i=4zt| zHRcSeXWwbrL4E}x^vGk6b`A`iu4(T)@~h`;bS06z0EMe_T+p5iqsm0P!^r*oa&8w^ zNFODtv4&%q>W!;Z;|R11Q?)w=;yo=}Y5dWZ^v}-r`-@Y~6!L4xCZEzI@?y1ke!<6c zeg)y!on8s*emD*Vv+N5ar18&JlIc@!FfXi7$`Lrm9;!8kE9Gc+4mh-6%4js9ps5J4 z=6srTK9dH_8q#qV3iqSoFk3DtC4>M4z1(NZS?LMn`d&o$gMoS3r5Fa|{^@cueG)AP zq{Bf-wSi+%j!NUGjMYpyOL{8(MjYnDQ|e!$Dc9GK*N*x0nDcLJLK(1Z1P!mrAfIxE zas|GkE|5E`1s6%OBp-jT_eRDrGM$Z53u6gGNJ;l?7)uP+4B1z^yN1uLNfc*0DUy)A4ihuTy%$U^huw7n+4u8i~#`>?n8|*E)Kg9RhcxBi?$(W`NWGBk+~$2 ze6OXGcNu$%6%;5I#~`7^--kA4(4lVZo1V{`YNx-%a|p$d>*;U>=c7oa9DdF^tYoOA zn=)F5D=NI?23;vbDovKuZoNZVC)&al z@9e_o&b5Y)K;iE(eH3+nCS^#t-P85{XvZwOjTayWz8XXW0q5X+!a&RUO#>i3#NIIg z(p7{L(m|c=+_C_{et3USitDMRYDjNG>A28cpVk#G?08yNs+z`uug@c=y>rNEAH&%n zB>!&{kftCP0OAvn6VV|do8bgMj8rFU&%*mZh>(2%ILsfw+Ve$obrL!65AGTqcb2M5 z>^cY|NZGM4keqhUR&ZXPs{p+g+^QfBG2C6aFT`{}P>~Kv2W8KCuT>@R4}AWCb0YZ6 zsqn6W5$YWnFTlCJ8$piSW|AX^o&eg#fc7w;SLUkl(g76#&_V_12m?B5P!Q5QAmQXr zg{yVi#(LMVP8)#mBUFe?_rNN>JL(y!UpfL)p?Z)3FHR!I?K9QV0qF{2Ku!SkdN4U3 zFof4z20-wjV@oWMETD8)?Ja)Yg&$o`gvoK>B6Jk~=4(k^17q%JVuv(+zV#k405}v( zCx@*w$iWC`4+DBx_n%-ZgATC(a?wp1Dmtz~vR)?*OP&k6FEq@x4^9~9n+9Z!|LJf# zO4ZVT9B%!|1xyzzaoEgowlJJ+w$-D|nE?S#(Sp|Sg8v*@tUTzb0n#x|O*$}r=?Xj6 z_9w0qN)ISXQJX=z-SXQPo8(bRuASOOF#>@7#c}IQr5;;w_RVe0TnAd=Nd5Dc4oI1_ zgqc9nKm>vT`?xSAk6 z*7Gj~bYF)(V3ofd40h~#DuSNPoM?0BxRN+nTv?omTzysoR3Raz)irn?Mc~u1BY0mE z=()TXRLE@(paHp)>DlD5^i=pz0f>ECR0JT$P!y_)8I`gLV-4Ux*{shSc(8C|Yud+Y~A3;`Xl zrJ+M*iURDon$rx@LxQh7Alb7|sc=g)g#d_525pZ`p`1Pm#+hZ0gH*GTDAh4rb-ewOXoG6Yg0uB6O$FQ|!}Wy+?5VkmCs?2|oid3d7rFwTmNK=j4m3-Ems zjOxbY)q!7H*$U{Q0TRN1pL6MiQKEylsgf%_Ft+TG``gB@76)$)NLv^$qM@`KIDUQp z04NqPCm#kd)_^of9+zUJ;Og}F<8oZPQ1n}{sCoJv6m-iSjzP7P>ns?%=FY4tWWByu z+#R*^#+)|wGkt8IQ9i#h!0sO`dBT9-kLX))O!mx&tvYk-If~5^fXjdQhyD9aBA2%o zQ6KUb`wzY|w=z)o$Upt*#D2ZF>BX3%Pk=Go`@=<}^ve^Z34Gw4ii>vMBDT7v(=GRp zx@^1{K>q|V`hA}6R-!=X{SGW%`18U+AA|w4{00~^oALz9>_#5T)FY}>{H?#PUs>Gt zXm8(MjcJm_@ELtS@Ept1_hncxVF2$Fy_5671?0@iL0OLZ3I1iR(;M^D4YA{4+z4`? zbPAnzn2aG@F;WGpQO_SYTlR@xYsec*Gk-K@b!b zMdU_QP|TrGJP`3pyrab1Xv8Ddq(+k{2qb#L8U_tw32Z{1t>*1dIa-COt8y>)Nh z+YfN_+8#l@PtBpgODQy@Vi66i%BJV4mQrwa4h^qdM!}aC(a>|L)MrNw{r|&wGm`og zr_zAhEE-&sO+y(*P~{SO{>Bo9kwc>@U!u`fuh6*a0 ztadep*RG+6y0tX5ZXHE7u-)1~Q}1k`(U-D+*nr$Nhf?pV1=OdKtt_4Tmu1j^Yne1y zpkz@nLm9zPMpwd1R!~UIN}9|-rZS9a^?4N2kWVujHc)Is0mU{J$aB0F-BdtPcMB-E zDD{U2$b4}g1=KE}-esu*rC)hE4JcnggRU)PD2v%smIxGh%6NtnTDywE>()>d1DVbM zW;Jf4xKFlF{LL*i@8(vv*D3y!tu%*Uo7K2U-V@Wjk;3Y7$&@kjhXKgHDxLf*QpvwG zg#yab1WaIg1`T9y8FGCQJy(%UFWi8pyiDV&mP_aW%C!3R;u&$DY!(nnP1`Bu)(%R& zwUg4=@R-c6&A<7E0D>n)H|A61ryHsNRwox}|Edh~D^DT6(qsk$Z%L!R2qBBNWQn(o zWN#V6ni9gAGNslE1q+_v^o9V*xV4)yZ@)>4n)kBplgG^4dl=F#fd&tXZP+NEjl9Qj zHbpxp9N(%m@-0giD1PiMy;U&%;4S5fw*)bm7g$@g5DKf!rO3KGIs1T;cypU996%N~ z7t+!@Z&A+O1GMbU0m@-p!oM$ONEx?xi}%bGI0X`d;djTMCNPBWWJh2 zzNJY5#|8|C(a>v37>&@pg~b+`C#F81;u<$gh#*`RGL&ovu#ADc^64R3e(wmq_URE? z&i2aPL-Kl-3MZ*)n*fF8AcKY7$#WhsUcZ}7<{K&Gb2ZTx3=3~x2Gd`_ETo| zoMqrGSR`~L=k9)bRfV#Kfvo%N1m%5plGc9qj{Lrg;k zH4QzJOpiH)k_AYcV9FIRs9l1%pc~HFXbjga6FH3F`Un9m3SuhWatGdWkXG>G;U#$t zBmY4WZFq2s)_+z+d7tz1FV516`$s9~-T_+r$3v8MdzX0J4EDT;+O;g`D{0*ATr#Ev zKOQ)S%^_s2;1DXF&tT>Y96gu-Js34j4_Eail)<2)MbQ?|bxI0{5wrzj3td@x{}_A7 z30nW)q(Fgf{quQR_xVYhuy!u>3iP5LfgUtw{T#~typR%`w@XN3pU|$cbt`D-rHsb| z1~9y@B#0?++72ZR41{;AfKl~@Q#5K8h^{`2RI#qp0hg;cgd*Hv-Ivx|gZ%$$4E1 z$FnGwe9Dp(7_FGEfJu>bjj9*o8&r{{XpG)t)Qlu)8es11myERe4`=Bw|N0x*Z{K|L z4W*{0whHIzJ_ZWC@(NAnj(ju=JcNE&?UJqqW9E|Ir!=umFfc#0CD79Ku!<~c1#mV) zRPlvi&SmjMs?Jo!7e!pd-yaBwe}DTQ`sTZD>D%wVBm7|d`s=UBU@)`_=hp$QG^T{% zH>{8fdst%*xh);lHE?>pI*NR&)7ph1Uc-8$2{5{9sbje69c4+^YouF7Z8o2Gss9I%9qmf)j2ezCY#I$x~Nq!y%#4{Zbx7s z#0V#g&R7IkDexxMJgmLF~V^2;x&M~@yYq5RnT zyywK;^jvKY4XRv3eLm`<0hc4*qJhymY>XYy7HCBtW-t@Efecr@W;VA3s9+a7*his- z8RTL1qKb+eEi~qB|BAtwd5swy*`G#ZO;*EljYaFu*1|ii)%~1Az6UGmK6H&K@rr+8~<4!H4C!YT0 z_X6XR6hs5+vM7MR*N=71>(tCg2gWsbJYnYI2pB-|zMP;Gd{=EN;r_a&GMM3vWY0lZ zP2?VDG6RafyOBm6Nu?)y{rZ1`^3+fx1y(GSZ0KK-OuohJy`_&(fISY!D7}#*9`iA` z3Lno?yv9-urzq*$uHz0?CwkhY6Nqv|b3ToJe=$Af@A6Pkp6K-y1)NWy{*{^3`)UgL zUg6{6WAWwVesq^XKIDa#Cpn-m>@An#$@`;uiq{m|hLol^8l0i3=AbHu_aI}zgF>3t z(3q>s=-H4y4ng_JlRqP$Jy8@`x0nI|r8tSqm-$%uxZ&x&vRKM)DNUnEA*Da?ppS(tXt0vJCJ$}`;*#7*dL?7b_tID5i@HhCSWu zd|c;)F}^j;VSO=OU?^N2i`UqPREc#gp$W3gg+-JzEFPpmf+5t9;)hjp?^C~&eD_SF z-;DO5pBta1Uk!05@4{)+uWnIGC^$jtG5C}!GwIInrccH?)CM36VFv7VZWfu|j}u7t zaO~$c{<Y_mWB(cy_E?-CgtUOE zd<0i6CBu{@bsR>#c+XR@1b7cy-Z<|V8U)b?kfp>Tuk0H;KGsyFF zEP0)sB?l*=bwLj(K_GfxRtrHk)EkO1DAoLnlWk0U9ckDs#-G2e0)baTQ$Dal5inYd z!UAmE--%#;n>5&=F#|lx^t(9nI21)5$D+yO#B}m3QUSf&3Lu0SySyxjvj;K=!oaMW z@5l37m|0BuyS)D+_49zuB5S(9P~K-K=Vy!80uoM`93KlXzOVBt-uwv;W~3zYWEjS` zrjikGj!a`fF>M1vh+!cY=UPEMj9pYRj(lGA66{wzx)uc88(Fq7?-^9t$Wu%mXrh{3t-3YRYu zU12YA&0{cY$J%<&CObGgH8`3$BfRVY=^^P2pwvfCHh7#x6N?ktZC|7U-qi^+VBZd| z3cxj=eMz}<5}^VJhD{U2TLcbtr!6?UbZ|87(YyzCc$#7wBt0y^;pg}ayv8yKK;2c* z_A%oshf6_7CwL653bc2fS{Jhj4J;bkVgbY^VU=$u%G)$io}!3yTW}890fMLSBPwhO zL;gE56TH)MGHcV@K3@J?=M1TG$B6GHkOcKliOmC$FMeo!1t) za998WQXTpYC_l&}8`#WkI7?t5SR6tG;ew*inw=Pi<|zzMVBpLjjI^X~BRt}$V)DDd ziBy2?RXysk(q>q?c&>cCFWEMTMuv^!g-0tbO%l2941Y9pUz}Yj>yNa4!!asR$r4zU z3do(q1fLUOhNrLr%Cqc=`p-TyZxB5bKhWkiyccbS0whvI8Q(AIT5C$rD;+zAUru`i zG!D@7jI}fuK*%urBh>|lTZ%lF)nhwcNRNfj$$pG#BPu{nX+UP{hG6rg`gY$I=A3Xa zp_9f=y4+bxb^4A{szWp-G!ChPy3etcDWJ8Gd3UBA5ZzRe69m4;DZya$V8Rql#sO;Q ztBnFqYbCsL*4=kI7Vp@XC1e2PgO+1bnIm6M7WmEyrc}KO`JryictJNWQ3vIC^f=_$ zBE&;3%xU$igLb#5R%p8KiEvIZX4E^y>fM}|6Rcy$OS(y$j5gz2WVE)gP|Q%gLj@vU zq64BY_1$(%a?*das7zDu;+$^_NL$#4^DLJ$kj5PvlyP{-^>E$g7kelckJ&rL`M~si zd8F;oyfr|oK@S`*5x8ye!RVtMD3rUt~NWt1aTiDNn^^nBM9IrVHnn65nzJ8&6S6UwrO@E9%(9T~=B{Nbr#U28T z+?CFqwabR_PVf(1t42G1f1aJ|n>x5}MbdOx(!=e$RPo5i4hFrCqdM@gQ~Opkog>gC zq^3SzI1oIUdt6thed79f)PC2dfaS__?eB7C`E!`|x3zD-#syLa$Umc&Yx_;Hnzk>U z;Q}Fmqp*DZb|KHMri z)D28r5}3FdHDE%BA=tJsGVYzK+^F;(_hab7&v74iB1T4^-)BAl1puKwPNB+0f&c&j M07*qoM6N<$g7PwE;s5{u literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle54.png b/examples/moving-saw-platformer/assets/Idle54.png new file mode 100644 index 0000000000000000000000000000000000000000..4fff9f72e2c9d949bfcd575a51373d08b44ab4c4 GIT binary patch literal 4422 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 M07*qoM6N<$g7PwE;s5{u literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle55.png b/examples/moving-saw-platformer/assets/Idle55.png new file mode 100644 index 0000000000000000000000000000000000000000..2bf6fce16fd81132ecc9a7b2c8e4629e7ee9db4c GIT binary patch literal 4382 zcmV+(5#jEMP)p)DR;YP4EH*L=+Wc z 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 z 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 z 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle59.png b/examples/moving-saw-platformer/assets/Idle59.png new file mode 100644 index 0000000000000000000000000000000000000000..0efce8793ad1770c49f119409d87caae1ea1a9dd GIT binary patch literal 4358 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Idle60.png b/examples/moving-saw-platformer/assets/Idle60.png new file mode 100644 index 0000000000000000000000000000000000000000..0efce8793ad1770c49f119409d87caae1ea1a9dd GIT binary patch literal 4358 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump35.png b/examples/moving-saw-platformer/assets/Jump35.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1aee8af8d2310cfc5866f4204f1fe48db08155 GIT binary patch literal 4815 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump36.png b/examples/moving-saw-platformer/assets/Jump36.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1aee8af8d2310cfc5866f4204f1fe48db08155 GIT binary patch literal 4815 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump37.png b/examples/moving-saw-platformer/assets/Jump37.png new file mode 100644 index 0000000000000000000000000000000000000000..8c0b3f8efaa5442b0e0ea2d9362d1b0116dae8ab GIT binary patch literal 4855 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 P00000NkvXXu0mjfMUmAn literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump40.png b/examples/moving-saw-platformer/assets/Jump40.png new file mode 100644 index 0000000000000000000000000000000000000000..b0c0f18039fc572416a067fd9e9a9c122228c3d9 GIT binary patch literal 4685 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 P00000NkvXXu0mjfMUmAn literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump41.png b/examples/moving-saw-platformer/assets/Jump41.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1970f9fa728e7a6f01abbaeb1c8bc05cce5fd GIT binary patch literal 5001 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 TMVrFW00000NkvXXu0mjfm`;gk literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump42.png b/examples/moving-saw-platformer/assets/Jump42.png new file mode 100644 index 0000000000000000000000000000000000000000..d3867a280600dcabbdf575b338f141df98f4fd81 GIT binary patch literal 4955 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 Z{|8*CLbW+easdDU002ovPDHLkV1lLsUNQgx literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump43.png b/examples/moving-saw-platformer/assets/Jump43.png new file mode 100644 index 0000000000000000000000000000000000000000..55a4e62c45b8c332b8f5ab4d81360414969ac311 GIT binary patch literal 5024 zcmV;R6JP9!P)Gkc7}nfJo>iBmq+C zkdQ(eEmY|cieN#wq7)US2%;b$1TY0sNQD3*sOacj^RLdVb^o|`jdzXm%=^51?{iLo zNc1KU?_|5)b>N(2pZ)#5=dF8Vt5#3&@W>ek|E&`cxFZJLcEuy;rC4-bHy+*#MxfRI zr^9ROcyvFLjQ-^d5qf<&hTdF>5jR$2^v$&xcXJ&gZf!)=?M;|)XEP!{--Pg*H5hU_ z8-c6G|6_s*_;4orR4u@OYl|_kDhGor79*@;DMnPT!04)#7+1Xpku~cv@#+RdU&}@8 zwM~ev-Hf>FVxMhA?3ddRb#o&Iy`TDz0m%30H1w)nh~Aa+(YI_qLdq6maCr`fm{7)4 zufq76wU{74VgyD)?G{YA{vxJb--hWowyW{aljXhm>st`}`BqH4y%`~gQhuL++?Ix+ zTSX>%RA!@RNf!E)&O?8JGUy7SEHR)|twKc2I!wB@5pe=!ssNaI<0Z_#`6`lb?m+Tq zuVIeb4teht%#hCrEl!jaBY?td*TJ^vcNB}f_C+K3+B|eC%|Q2(O!O|zMn6%@z$=UJ zeEAX#t5`1XLnv!8>FP$r3zTWsx9j2wWA3e8$oTwqWZvG5%+G1B%X@!B%B`J96lhct zeKb*%(`Jg*^T+P_b7~|U%ZXw zUmU=SFAvD;JM#Cp6i~K6qk594903}4Z8M@IXouh0fc_`bnjajm!*K|x%0So4sR$Ic zbQ3T=OgHLZwm`uQDK}!vxa!ra76w|zlw^q^8Mj_nD2oNk@-N@Ps;}O|ny(IG?cIY| zEw3xTdRGDE5RND(O_W2|W6X&b)lh+>KU<4FCz6{F9QUnb5m1vUP*TLw>|lBdm_7<- zzLOiR)GWl5%tdi=TqGCEMO#qT-aU-YAdk^!z+@tY` z@rJ6Q0!K;OA8~6n0(ZqW4>muuh>X zFyo|)Yb+48ED?91GS&)&jbFcyO8?MkW%AUqtq| z`;d6+RaG9-{a86S1N)HAUU>3gyiQJoUs)>rE+>nnn68xO08^H&f!8^{FeWhN&QLdc zO=Am#?XoZ5R<%$eo4zriZ29H`Z2Qv*dG9cSCl5iZ)~&c`Jk|aW=({)yGizVM%&&Gx z%Fk679bUN{&sQ%+@BEA>2gfCQApEM+;d?1r?V(`Ij6^WQ`qfO*3XW{rTMI@XEp{O&YP|93SG6n==v@bP%& znP(mfhvpI87o#pO*8t4#8X&z`PsxZ+1dLx*I&4LAV7oNO2}}wC6wKTQ6;n|k7>8nv zz|; zaPsr>(WXtCdf~Krsx5q$k3z`R#pqQr4_!|`=Bn6Mk_?~1B-m(0Np?8?_Bi9HeAx~R zDmT(KQ)+~nmDn7zP-9kN4MWvXE#Lp`&kE#!@BJjN_rU+GSZfHFn_-HSNtq6EVVd;xq9^~+O}<5uVO6wL;o)5StJO zfUXyk5S*WezC~FGDPDm7rSsK|=u%dkadsyw0CUu!?j(g7YZezv;0pYM)PQAMuWA~=p7x?ruPs7{W8yz}yXb=#~ zo{bDbFNrT~X8j9|QliPBv`_B`+b1*8_0%kMKc9+zh1nQfvIxVkNXC&qD7;G2arJs> z0Tzq9%`sex#a^jd(>SGW9aL2tgDR%)SzqkHsCP4d6@>e(b=x-ZKR6ZLE3(kFNNTKt zIa+HqeVTqR20kBAF|*O*LK+4X&BKt=#TY3rG_G8=6wmkL;r-E61V~ouU66r6 z5?>53s}Lz*CW%W#%Fc7QSm&_5u_|I~BoSPk;WWgWuj=8Q0|E*Y1u_1x85~(9O1iZU zLyMQ7>zZ)&zDipTp2@HsIZf#>F+ zcTpw=l`S%QAQMbXO)f@USq`rYvlNU?F7N?3mkGycGOd{~t78UcrgTE0n>}w?)l!7r zd;x?(_3xmsYG)`EGiI(`%vmhN_c{Aa2akc@ckZ_XgzzK9J z04+dN5M7LrI1Z%|mi6a;lJ5K0`6z$uL28)GSrQ`*S7Pvul+>$g`DBLdlzO++;_lN_^eN6(Fhk3wIh4T3tU@Juo|>u`#f#%^ z`FvUzj&mnY^)N68njN`9ast)8*sx&p{chrhL6_1bz!HYxHjF2>d?TjRfpTgZygr(u zV5s!Qcca5`=<;4HJViCEVf@d|)*gvq29_Dq|52it(Beh#JTb-CC6O>M$PULzIron# z)Gis26ck;JcFAD@Meu8hV#x>vZmUsd9%)0A`!u@j(K-PE1ueyf|-Xw{lXC zF|shaa&<9hD>SXZw0v5Uny-NHRTyHZ0L@gS4 zN&n*+@IRk~Zc<3~D#_AxtD{6I^gNEnYn|hHe6mWI7e_gJI|Is_k# z7m^SpVC=INNw0yY6Tx*VQRQ1`l=lJEjt6$!wv0iim&c*g zOJj}KSHxZoH(*(yOhwfT$yrUbgHEu1$qpJn&y;P4qF|Es_Dy0KG&@2425n~CV}^O6SM=G1wJy%eC>Z`X)kL(7``q>VPLUr-3xg+7aaU|R} z37{>b4M;DJQBZbBuR5zJ;^8V%NYQm6nV_7FY9UOma_H3oS8?gL=VRNXXl z7)sQvFCGMA_^=&}1mMnZOi~JhVmWl{x8{N!uF%!d_T_q#T{1<)5W+;&7g~w zg;ObY)MHoBXoY8YF9vGHpZb&|sovv&0fjM%a67IUrsttM5*{mUZX&Od8`|_Y*rbWG z`V}8@WU29`yzb-cUG_(-V(3l`u<9nVn;Ks>kA46U-Adib*`+MS?44jJWWSNI2#7z| zaph3BEEyr)bQ~DX@wNp?doQF1?Z#m#}+7V$a_!S2r*G-0k z2#N}GSvUwC*A3U0<7UMjdF{A%I9zfD!%%mQmcVXeiYlWy27!RR2Gqebb$SuOJ(lpPRj4;E`y%9Ym!xh@s5*{GuF ziW-=izTb_tLt(b`ElF<1|CT_4GVlEHLhH_5&2fM>eDSI%DyKn%GOHnF`yiQ#P>uUr z2}aS$Ovz5Vsc*yn_MkjMt4tksUvNz8jXA72c06een>f;RUDL3~zX*cEGMx^xQRHZX zE_=!eij)p4DVk^C6$P;B)ZsRV+!qZ%#uVRaZp*Pn19z8h_UD0<;8)SGQKPmZ)~%HL?qoVw;W}QZo{J9BDm1V7BH5x2m^y&&GgJC30w1Zu zk`%|C%K{V1r8y5ZDwa=^HY+e4mxURvetDV(!ul@0&JH&~H4L(ZsN;>IN1XHWoTi(- z{M{o8>25h*pLEl11I qaYu*%h7T)>hXW;R4IKe7!OGR0000Gkc7}nfJo>iBmq+C zkdQ(eEmY|cieN#wq7)US2%;b$1TY0sNQD3*sOacj^RLdVb^o|`jdzXm%=^51?{iLo zNc1KU?_|5)b>N(2pZ)#5=dF8Vt5#3&@W>ek|E&`cxFZJLcEuy;rC4-bHy+*#MxfRI zr^9ROcyvFLjQ-^d5qf<&hTdF>5jR$2^v$&xcXJ&gZf!)=?M;|)XEP!{--Pg*H5hU_ z8-c6G|6_s*_;4orR4u@OYl|_kDhGor79*@;DMnPT!04)#7+1Xpku~cv@#+RdU&}@8 zwM~ev-Hf>FVxMhA?3ddRb#o&Iy`TDz0m%30H1w)nh~Aa+(YI_qLdq6maCr`fm{7)4 zufq76wU{74VgyD)?G{YA{vxJb--hWowyW{aljXhm>st`}`BqH4y%`~gQhuL++?Ix+ zTSX>%RA!@RNf!E)&O?8JGUy7SEHR)|twKc2I!wB@5pe=!ssNaI<0Z_#`6`lb?m+Tq zuVIeb4teht%#hCrEl!jaBY?td*TJ^vcNB}f_C+K3+B|eC%|Q2(O!O|zMn6%@z$=UJ zeEAX#t5`1XLnv!8>FP$r3zTWsx9j2wWA3e8$oTwqWZvG5%+G1B%X@!B%B`J96lhct zeKb*%(`Jg*^T+P_b7~|U%ZXw zUmU=SFAvD;JM#Cp6i~K6qk594903}4Z8M@IXouh0fc_`bnjajm!*K|x%0So4sR$Ic zbQ3T=OgHLZwm`uQDK}!vxa!ra76w|zlw^q^8Mj_nD2oNk@-N@Ps;}O|ny(IG?cIY| zEw3xTdRGDE5RND(O_W2|W6X&b)lh+>KU<4FCz6{F9QUnb5m1vUP*TLw>|lBdm_7<- zzLOiR)GWl5%tdi=TqGCEMO#qT-aU-YAdk^!z+@tY` z@rJ6Q0!K;OA8~6n0(ZqW4>muuh>X zFyo|)Yb+48ED?91GS&)&jbFcyO8?MkW%AUqtq| z`;d6+RaG9-{a86S1N)HAUU>3gyiQJoUs)>rE+>nnn68xO08^H&f!8^{FeWhN&QLdc zO=Am#?XoZ5R<%$eo4zriZ29H`Z2Qv*dG9cSCl5iZ)~&c`Jk|aW=({)yGizVM%&&Gx z%Fk679bUN{&sQ%+@BEA>2gfCQApEM+;d?1r?V(`Ij6^WQ`qfO*3XW{rTMI@XEp{O&YP|93SG6n==v@bP%& znP(mfhvpI87o#pO*8t4#8X&z`PsxZ+1dLx*I&4LAV7oNO2}}wC6wKTQ6;n|k7>8nv zz|; zaPsr>(WXtCdf~Krsx5q$k3z`R#pqQr4_!|`=Bn6Mk_?~1B-m(0Np?8?_Bi9HeAx~R zDmT(KQ)+~nmDn7zP-9kN4MWvXE#Lp`&kE#!@BJjN_rU+GSZfHFn_-HSNtq6EVVd;xq9^~+O}<5uVO6wL;o)5StJO zfUXyk5S*WezC~FGDPDm7rSsK|=u%dkadsyw0CUu!?j(g7YZezv;0pYM)PQAMuWA~=p7x?ruPs7{W8yz}yXb=#~ zo{bDbFNrT~X8j9|QliPBv`_B`+b1*8_0%kMKc9+zh1nQfvIxVkNXC&qD7;G2arJs> z0Tzq9%`sex#a^jd(>SGW9aL2tgDR%)SzqkHsCP4d6@>e(b=x-ZKR6ZLE3(kFNNTKt zIa+HqeVTqR20kBAF|*O*LK+4X&BKt=#TY3rG_G8=6wmkL;r-E61V~ouU66r6 z5?>53s}Lz*CW%W#%Fc7QSm&_5u_|I~BoSPk;WWgWuj=8Q0|E*Y1u_1x85~(9O1iZU zLyMQ7>zZ)&zDipTp2@HsIZf#>F+ zcTpw=l`S%QAQMbXO)f@USq`rYvlNU?F7N?3mkGycGOd{~t78UcrgTE0n>}w?)l!7r zd;x?(_3xmsYG)`EGiI(`%vmhN_c{Aa2akc@ckZ_XgzzK9J z04+dN5M7LrI1Z%|mi6a;lJ5K0`6z$uL28)GSrQ`*S7Pvul+>$g`DBLdlzO++;_lN_^eN6(Fhk3wIh4T3tU@Juo|>u`#f#%^ z`FvUzj&mnY^)N68njN`9ast)8*sx&p{chrhL6_1bz!HYxHjF2>d?TjRfpTgZygr(u zV5s!Qcca5`=<;4HJViCEVf@d|)*gvq29_Dq|52it(Beh#JTb-CC6O>M$PULzIron# z)Gis26ck;JcFAD@Meu8hV#x>vZmUsd9%)0A`!u@j(K-PE1ueyf|-Xw{lXC zF|shaa&<9hD>SXZw0v5Uny-NHRTyHZ0L@gS4 zN&n*+@IRk~Zc<3~D#_AxtD{6I^gNEnYn|hHe6mWI7e_gJI|Is_k# z7m^SpVC=INNw0yY6Tx*VQRQ1`l=lJEjt6$!wv0iim&c*g zOJj}KSHxZoH(*(yOhwfT$yrUbgHEu1$qpJn&y;P4qF|Es_Dy0KG&@2425n~CV}^O6SM=G1wJy%eC>Z`X)kL(7``q>VPLUr-3xg+7aaU|R} z37{>b4M;DJQBZbBuR5zJ;^8V%NYQm6nV_7FY9UOma_H3oS8?gL=VRNXXl z7)sQvFCGMA_^=&}1mMnZOi~JhVmWl{x8{N!uF%!d_T_q#T{1<)5W+;&7g~w zg;ObY)MHoBXoY8YF9vGHpZb&|sovv&0fjM%a67IUrsttM5*{mUZX&Od8`|_Y*rbWG z`V}8@WU29`yzb-cUG_(-V(3l`u<9nVn;Ks>kA46U-Adib*`+MS?44jJWWSNI2#7z| zaph3BEEyr)bQ~DX@wNp?doQF1?Z#m#}+7V$a_!S2r*G-0k z2#N}GSvUwC*A3U0<7UMjdF{A%I9zfD!%%mQmcVXeiYlWy27!RR2Gqebb$SuOJ(lpPRj4;E`y%9Ym!xh@s5*{GuF ziW-=izTb_tLt(b`ElF<1|CT_4GVlEHLhH_5&2fM>eDSI%DyKn%GOHnF`yiQ#P>uUr z2}aS$Ovz5Vsc*yn_MkjMt4tksUvNz8jXA72c06een>f;RUDL3~zX*cEGMx^xQRHZX zE_=!eij)p4DVk^C6$P;B)ZsRV+!qZ%#uVRaZp*Pn19z8h_UD0<;8)SGQKPmZ)~%HL?qoVw;W}QZo{J9BDm1V7BH5x2m^y&&GgJC30w1Zu zk`%|C%K{V1r8y5ZDwa=^HY+e4mxURvetDV(!ul@0&JH&~H4L(ZsN;>IN1XHWoTi(- z{M{o8>25h*pLEl11I qaYu*%h7T)>hXW;R4IKe7!OGR0000$}$a?X7LvyoAkpeh9qxO+wcbGtm8VGI|%KqhDzz`WI&*_-Y3F zoSKd9`=-OXXc*f3qi-&2!_ejYEcB?Ei=euB=uTHD8EW_~H z6&Q76HOAatgK_uPV>G>n55I~O1YXZTw~BQ1C`(80^10|+k%a-3 z3-C_WA`H8hjp5bHF{)-I#$I2I@z-+@Ub_|%bz0n7hlu+d1y<1hnXfh=$7Lb#t(c9j z)oJKjItPIzspwIfjv#?D4+9BGNY!G3vJ@k$R|pV>F|lqvqHk=(fnE(fFT<-j~Qq-DbKs!WDgX(GIfNHN6~ZJDW_1vo$Ye6tcZmKW$D)ku;QCTSoO_k zSpDr`dOa-fml7=gdFF#$@t(L_+r)1oNqMZm(7NU5S2*|O!|6D$Kdd#$0!0VIs_CpL z#@_}e1O2E(52{>fOCwGJHe9YgY^)iSLYyv3NEr-)fvo-ZDAs;=3~T6B-hcl&mjCNv zEckXGvi^A=67TIq%*}T(scwTPFpNt7klV}Q^FjE_g<~m=hq-u`0Su*5aeXTJ>&9EI zz_7oB(!r0pzRH$HT!r}RXWswFrk2&Dlr`TS!8(Gno?^ovKgZ_({0dW#EP*K`0G$F& z2+ABQ=@kF<4nz?cu5O&7?@+4tzp?n`fpOU}3YN-5mV(htd8%F((4hd`Qs6+qWAACiAI}WwdE7GMW-M$ z#-Ck`m~XdXLfsmSpi0Lc*8ln<_#KORIdCi`q?W>&Pk`~#J%+)QYGAk`NmEB)s&z0M zBn=o$DwW|ZD$87fmQxz({<8b~^Z4R_%8`9&3);79X9q=(U;XwC^vsDw^$WOs8doVJT05DQ^aWQE)5;MvqAl^JOsXF`PD#S_X11zA5!{ACGxx!3-jd} zuv{gz zSjB7No=m4wH7f;c>7;x{r4y@0I$!E#QXlR{X88{M+n>HiW7`iu`~Z{5^s|c5A$ffo z1^=3KSkFvSIt1cfaFnbEF4h6Be)eW;fiz{L$6d4_EW@@aWHf#$!sQM~@yMKR+LVfq~D4Lecg& zZ=mzBY4EFSCWZA<#e)@Gy{>b_ASd4ztQKW`eBkx zSQDy8)f)WH)Un9`8jIIE{tjK}`25Oe!@D3JUe6nh!-~Q1JT(>8lO)j# z@#v912Yrj@Vlb&?SY@_A8GUU9##XOFm%=2QYMw}`(ll9ukX5`&hLf$9Hfw0wzOxZS zj-}vDhqwN2Fs_S35O6&MK6G)cc~m9K5}z*^j}w#OaXbpvQ`6D)QUZFB=?0f(iMNE2 zT1IJ5##FC_Z$Y9|DXVV8hLlo%qu>N2vfL=MP4~{n#XUei03?GqLc$l87KqBQo6~l~jJ|q(&2v@zpsPNvXsK zsF4GbW8Few0-mSCP8__`7QB2G2Fs< zSZUwpD|8IhT09ph?Nfu`PD*h*G7+BC@p_+|fq=YZX`%+w2@R!_8A)k0hSU;4UeTAn z?{RTDHGirrwitUGUh*u`l%v7X7qR-u?UebVpuv=4Lu#@Sc6Swmj>b#V)~4-iPp?A1 zejVmL;pkeEM*B#B7gt8QIHt?gYZb*kA24p8O@!N_NKuUGtEuQrr8=-+4*HbN#UKJR ztSVc;jH_NPX=J$=3(pJF<)FALHs{ZLVvbVl!OD=iT5)Ri((gA>N$2r_(~Ny+P~Bn- ztfguBqiFoTpJ(H~vT7K*)}|{cyaYn~WVLu+jFG0ZePU4a!g1O zq|QH?+QT_J1YN3A=`#~GC@O_amtyERrpYn5>>ks6V17R>0IU|* z{o!ysJP~ZZ*0V9_ay0?nOHvJBmWaO$DxD9vlhN=vJr$m3rzzFY!O1+8XFp5naP&oU z9S|#sM+k<*O6q0^^}Q5ytDzaFIvu`r9BlGkuCb@sD@8$>F2}+b$o*(D-kfvZHAX=> z7$G0*d2$N8F3f;meiDI66EFic#e`CrDb3tZM8V^$DL)U#kXAN8bhUj9ko+WOqpKnO zwC{HzkMiZ;FHv_S*iXc0XPJ^^EX~U*PTc(hzB@r*xgquS>eDo-w z_f&qRVaw;Bzsrl0U?8Fr{``v?lrse76deOqQQ0RAyv+ioLwaB3E&C%>8qp5SG>my) zrjD{OnZTr?Hj_4iA*|50ip`V>hV1N6hN$?JT;kH^x*QIA7?vh zyWpOL!g7UUhD`PxeA1#4Ql}jhzCaYbx@c~$lI^r546ZaRavHf&8nM5a&&9y|>MZyb zCEKQDhGRM$1(#386U1-@lK~x_Bvs6vfa-ue41hc@#HbXztgY$rN$MwirT%M+oP4Z` zODaqkl`=#f3_}M(>Ed~2s)9oMl)j7J%VK>=GlA)_c%bwxDvgxCn9s)w7|!uP>R!20 z_@15tCvtq(z2o8fF~zsbIJ*L`)fHt6dNJ`Mo*eA>v6&N1nDLX#`x+f!65XYROio<&*aahi@?1Tt3|++H`Bc2vU{{jf#b?V z`HFFVvk7vw=u%2$^NQM;n(GtpP)7o*ss-zU=ICC3%)KgRu}8Zl-)nsFx_LALm&q zyyVH9veSDb2+{~RZ_^;zl%%EF$9k%T*Qc89M@KbKI;^Gy|1POSJn>M3DilQ;6iK65 zqWES3!zmz8`0B7(o|`UZkxMG~9i6GU^156;_jiPKG2 zkY(BGKK(z*~8&j%Yam>iF%B1wyP>;G-z9?X9XDn z>2W}Lk}GxG{JRW@o4tl$_}Lw*)>)U#A)+zQAtBU zj%zjbY%-d&A+>DYqr)*&F|8lsQH6oY-w;>L3Uk{?U4l*LQmVx_O$k3WZ-`mP5i z2n5?alc(I?TAeJ?Z#)IZ$pH%-He3S0N^w{-#9l#^UQZ~eVOr5=xoDM3hFMYy|IBei zC>&OX$SeOotBETp|BWNTCpIn71Tl2#gDzJj3ls^IM0^e(1PpfP9YAdm}|zY`|O~999o$xzGCY z$*@nzm|%mW0b&JhQIJ?6ytH9kEsX4fx2O5zttfxI9pP*He*1);Xg{lm#2-?6D<}kj zTL4Zw-k&U@Q9I$dX?V*8!_`5qvcMrVd@x#i2xo0%5I>>!tgLo1fzLdV_VENJv6n#X zxR9W%3X#gjy%2kkO#i$XMd|LiI;7=-;dY$;fDf9}gR7LJ76W1rVZ)?X2FEA*tj}Y3 z9kPNYjTnlkjsD)14VRm`<7z3Di$bR*16wAT4oe3~X_vW$ODTDUORfSWUb0h*50$5| z*E}0cH#n?#2afc+N-3j7kwz%IPc9M;Embk@G_SBZtJSk8)vB|Ja+&4y;u1_LBuyNt zs!0zi&FQV0Lh>l_6i%N*kp?KL`7}STyN%7Unex@0KUqzqgO=q0R*$xJELCQoJ~TEB zj6+U{YW@hQj0wD!^M(CjEB#erT+0O`PjOyVtM#@;>64SC$B@ON!xL?jGs9`xy3knF z$7n;MtPSx{Yiv3T)Pj18gu*AlVAuqC^2uQMBSy( z*M;ova59u)^`K;n1jB2>@<22{3~hs>-Rrqfe*;Wi?WR4k?XYaH4XRA|=k=R+`XjW4 z^_F8T^q&FBxUVk`X>jDu;8g>lOG-t2m7CNP9hhjlGhn;bqR(puh6$SYO`uw=zu1lY zIvi1t21tX%kJ+P8-5n9vr@^)~Y0!<=+=H4#*a~3Rv~* z$G>#{u>D;@<4|I5z2@zRq#(|oC_u^Q!{{}jgkY&7di z-SgNwWe=2z+)|dHDpe!PjdFMJ7u+`G-bL0~DiZ7#y6x6>2_ClxZC-`Vb?*e2$serR z0#d^(+%bF5FFFxcnLH`MfErN|uPnBCl{Ov#xsB(mDv;=v74`St*5JDheD{JuSjrRY zZ^c$7zPkUtf#ar7k-WfZh7)n6fs}9jGia~c*|H$trgdx3`y32!h0?mUZmnDE*1ENB oty}BXy0vbtTkF=kz4-0_0j4=ZZhW=cwEzGB07*qoM6N<$f{10n;s5{u literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump46.png b/examples/moving-saw-platformer/assets/Jump46.png new file mode 100644 index 0000000000000000000000000000000000000000..e7eb3e4da6c7a609b0256d5cfb765b60ffd90c72 GIT binary patch literal 5074 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump47.png b/examples/moving-saw-platformer/assets/Jump47.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b515c0ce9844304864cfac6efd28c71347f608 GIT binary patch literal 5019 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump48.png b/examples/moving-saw-platformer/assets/Jump48.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b515c0ce9844304864cfac6efd28c71347f608 GIT binary patch literal 5019 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump49.png b/examples/moving-saw-platformer/assets/Jump49.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b515c0ce9844304864cfac6efd28c71347f608 GIT binary patch literal 5019 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump50.png b/examples/moving-saw-platformer/assets/Jump50.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b515c0ce9844304864cfac6efd28c71347f608 GIT binary patch literal 5019 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Jump51.png b/examples/moving-saw-platformer/assets/Jump51.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b515c0ce9844304864cfac6efd28c71347f608 GIT binary patch literal 5019 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch14.png b/examples/moving-saw-platformer/assets/Punch14.png new file mode 100644 index 0000000000000000000000000000000000000000..e62cf671e02d8dfc28c80a3c3964585e11f2c552 GIT binary patch literal 5003 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch15.png b/examples/moving-saw-platformer/assets/Punch15.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5f20e191cf9d0d1e518536e57ec65e81cda174 GIT binary patch literal 5012 zcmV;F6Km{=P)Px|PDw;TRCr$Pn|p9v)qTgm_q7kLB+Ig78(YSfO$h{wnUG>$Hel0)hXaElgV3Q{XNf-h4I&r1gvo`LlYPWa~NfegBb@?pVJsu z%(!C46;mI9amCcfYuv|-D`s3V^${3XOntn@eayIGe$R@T@fYW)OveOdS{vZxGO%qM zRv5$bWB7aeQQX>tx9@xY4_>LG9^mBbKdcI8%tFJgR%DuTa2yAgvS2H~fh~t^*>G%I zz9T3VD};R|^lsRJHP<~f>M_)(h1$*@@t}_Ss|Bj*oH@u$D!`5bD^jqPrC|_+Wy7@` zxV8iNAsB&VL4IrtmggXLfWGd1*!J97tiSu`BOXs})2;oix(CvB^Qo$3@o~tsHv)lz zO&|nefDndfJMb(Q8QX=&BL!q@C>EdqD5VgoSm4B28@)UB;uq)KTlbi1pKk4E)-{Nk z4_vBpCr*VG#9AQ&!-8Wuq7XtLjGXNuXJ?RgGRPP}1jh4|8xl;67=elq#vyzaBC-|2 z46tS8I=puCkLwy+?NhGp%$jdLXT>$jZ7o2RBblBYmZi-_R6-ybG&tGxARvNrEFRi~ zQRfvFK;t=IH5I}Lx#-7dHSb5<$Y93#0)2;oinr?i|^EW6v;{ZVn7$6QT z@f$8&WE~HAJA;CoMWfSzMkj~7lYwV>aBb?uD5b(h)Iu`~RfIqh3gHAO5l$Q+_AK=E z_Tl;Y_tZ4T+NWIGnZw?6_H&;SC|0Pne-JR*gtRZwP@3F4n!E-yIeAe`#`fTvh{T~J zYEj^iHlq}bQ41B598?kE4D|Kkh526{cAT|MxAwE%^M;+zep1;v4`3c*L7uxMj+ScC z4wlLwj0s)=&8}8U*3Q7Sw87DOs&7IlbiJ{PVRtO7AFs>#YY z=-s{ts~3OkeT8$_n;reg70R2@1e9q$fF(WxMlH5P8UiS|IkdP1w0MmINSlzGMxViI z(NL5E+=dLcy}1eh{qVCG*x!fFMRPHI(Fq7L!2Z5olp|lj@LZ?hVaLkf;*DGX?R|qY zd9G?Y|Bnz41gQxSOtr(MsU#-U>NSaC3QitbTMS4PmO9%i1yeDZLKYieS%;t8 z_*Inm_NCvpoir0C+_VT2=g+}FR7SB_6vGqqEqHiw?%ls%FmqPkpi~&^WW!8Qzz7_z zmYg`;ELyw*TD@jWa2t?!vhp3ztyW4hb5Ve6W7o#*c=+nOQQFlzq|r}4>sZXb^=xE5 z*bcwH1jI3H*M)zeh&AWEKPGj^6PSMg$5ifw$xwb|oCE!ehQj}#@6fr5HlvAdBdC}r zw?Xn3<}?SZg`t@~Wk$XobDF22_kXwH)fKDo_)|~d&2?`M3CGEMnEuImX#d2?a2m5v z#Sl&*gLfZ&4V(Yrxg)NeLvAqp#T%6JLmfwK^W5oQL^(|297)=8PDUIpp|ob2&?si) z9b!g01_9@{pMrTU#~Hwy1x;n?(xq6weEDI+MZU8YGj3mm=2JSv--YD>uP^-P_ZQ4j z_k2X<=XIoN5tA@L2#IFI+9z8DW@4rple}hu#3YXyu-29yI}^7BlTH*cF+FKwng+#N zZ@q<6PB}#&4SMm{HB*U9v+rGumNPqHIX1c<`8BrP`{EIWGw9;89$%`gtSgx*Yy(B$ z82`eA&T_@U(roB#TfN3qF?7h)U=qjq=SP1O9l18iTXb}*xaHp7UL1e?@#yO6de0=I zW#KXCTy_xfMW?q1)*@>bU?UyTHR;^lv1q&7on|ZZfbUbF>`4PmW2$pB#_0x`Q zxsZaH^0#NJ!h%_d%XGTBEx`Ot)WT+yd1qaeIA7*04AT=OhoSS$hz}yfBrb)BaBA)t zT+(rdzFyU9_wLb1L|hES33osAD&GCZOGnI{(hGNd?-J!r zYlezqF(a)S3vhH);=h^gvi6}b$x11Zl~SOR+~ttrIVS6sU(b4Y^e?}Kd4*$f^Jj0t zbj)X{8XgVOZm0so zdMcO2?_OPtr*8ij9C&+I-EcZSJ73fi94JZ0FR4hGFcu>p%C%rQ7NUJ6_?z~k>$a!H z1X2ae<4aXk4A3~C5&1#`qBuqvM+l<`QN)%KeUENx6OL^3^DI^&Fm$1$^L}m!awOnF#yK0>$Ke@+poL z$_Nn02264#V`>74Iiep)*D>5z#MY~RS~IAMVwQhGO`miWT+c;dp!fpB9APMfU=5?4 zu#QlixCVCv9j8L1`a4)(6$A*=4(EIdy?EJg`8WvD`!m%r^Q?uHpi}|qCNGN_7 zXh>0jFbEKZ8jMZFIJ!L0OC@YtF~9LlRMM*hR1?2XmrP()p1cgymh1O)?Z%E@Z^FJe zwxGD97c`;Cm(3Ob5z~xKk60AI&jb@i@GaJKb-YaCy6Noi*A8axvp1<3tw*68`qE7! z6rY_nzK02zNWfTT;Y`+w%z6>w5R@#LFgqp~v!tREK3#~)jHZp1b@u)zUcy#d1ly^lU9AV0_<4;QNT8 z7}wUYv7n~6Tc!#2_q=a z!iI%I`-zV4UZU)_2Dr^xakf(TxenNoWJ$6Ar)#n6A78E=%*WT>qe=rs?O(XQ6H+lg z%7G8xFC!=ih(q1Ar}Je}rNNkYX=dpPJdHtVpV$>yw;F!a#R?>1bDAOP}EeYK!O?pu#aT^51I9(Hg1WXu-IfXm>utb>7J+4Gg49rCKdzQ4G}*l|v1NzaV*mmZ+E%O^d)7eWY~Iz9eZ#B}*?N zYqJa^-zRmMaRrHX#H37ER^n`9C_>>o0S$!Mdd;Ip9?ZEv|Gdh#H){wIk&G$Pgcy;i z78Y>y30$T%U?dF}C>n?;DXGd6XKRLEy_7O&6+z&b2Pgj0;Ng4BgD~iHnd`@5M$xVT zI4wDBz4oyq2FE&o%^iw^37D&J9oc{p-$GD+fXEMZADHQN#1$~@SME&qC zFFCs7pins)453KC**$=`--p{?fHN^)m#?YEw5)}{x?M>g!3B0^ zy#&LgF7S1>>xYO5B+xYn-xEJG2vE}066I7iy37iLRz;OGD!uN?c&nnTr20w7O(2yb z1Y3Gw7cv6Hol-zF;A6|>|2pQ%vCe$yi;_|$)il9~dV&xkp#)kjG$B>ep9M^6K8a$g zfE)tnAZ66@=nND|Ma*aaogNv3Gbu0q8D~NcZhHfYYr3%gwiROv$NKQ9+mxi|F%Oe! zGc6CQltM5eou2kJLz$7RDkQ!q`D{9YY4giiRxMnrfzTYo?mh(D_G=(5IXP?|%*2~A z*l_B1#um&;FMK)$!|GY;5Jmu+4uKdmVm2A~`PvB|q82VXRs78$Q%a(gS))n|rs3#F z_Qwp^LVUnS`OTeDmD>}kl&pp`AqOt^Ft-Y}AHbF?$Ihgz2(I8UiYoZbVokBUBYLX~*$n&lK4?13m$x@}IwL4`iiamiavI2x^ahfs$ zM!Z+v!^YFUJ7%h}j(O%fiAr+N$w|&o1%|$b3;bb>aBoo>2dUXGG97F_295@#_s7WR zYQ+pS{Ir(RThXWjK8Vt9b|da9!)eNj$q1BY1BYPPf+d)oi-BKl!Mk60W=!B%ohz=9 z4J$e{ngWb!5g__q;%68m+E>&`UgA3rh9W9TavGzagZxag9$wi^bkNQsmJvA@#sBHT z&bwDyEtejzyv~V$=ZHcG#cs;NY0klJBp9<;Wm{0?5O06 z!lz9+cisA=)pFHbl{;yQ03$4&)afj^qM}Nom;9e>tTM|UsUxoDk!%}b(HAN7KC=Nm z55JyHaMGtwRm@wgybC7*L$x$ifuS%PJZv~^Y|P1;`Ph|8%5_P%H5BZHow){C8Y z4&LHE`LE|IJ~gRWWqE}v;m8I%;RIZg5(WU;(qFLr!+=q(;o?^>h? zMsgUM71fe=Q&WY6-bGWG5dhLf)!@^lQ>En)0rtZdhr#{Fm@1`r8gr0RpnbFRElsE3h-UrsyJO*xo z%N*Szj+SO~2pA5QW*sW{n|rYB`jIc;);y@808PLDVhQz9DYFgX+S(MQpP=&)iA?6j zwn1_AHthRR#eWQ!&QyQj`k8sEa9W4lhlw2lF?t>HqTe&iC&4@WvE}O8mrasujS9@v zI~FRpqe+rMX~9*OLutNZyew-b&%w4EM*b9e`58aHTuIlE{>3DB?**6VFq*!z_(yfk zwXTzg8bHT`OOzU*pAng)i(>l1=JLsQlDvz7*SoRjYs0q|4>#Ev4=s@vtU$>++W8JM z3#y9AYAwCqF;NUJGX2{ZixXy;)eW12rj#UhY%oC9$+&4w$GiR8vbOOL?^wBTm{GUVZ_Gk$oPlI4ozs6NTSNy9j-QMD!8 zzjT&rJa3LpFbRe!L%$DhkwZB|`L}z}eNf(2kAojGQxbFfr^U)?Ymfp{JK<{8RQB`n z=`zdSdiCh~wKE=EqL__uzomX9)Cy^A6!U{i6)Rs2MnlnSUEGW~I4Z^cWo*6nXJc~T zS|>S@^TuR=+;k*07HclEWGaPe5|>)>X=50ZO2W3;-^Vc9|MC{>{L10WjS&xK41aOdieX;i9X&xB zOo|n9&tvPb=j*FSeg83JG3ZjG9+>>43OjvOCS>+*9O8r1l>)~Ci@}XG>{B^X6Cdun zqXIMKu0^V8(Hz7@KTYfeP_=3X#lOT619rwm*nI$-ulU3CH=_bGYxz}*OBw0kHYI6q zWwYGi5+S*pyj!}lG=_cJ;Z#u1_oD(c`-SVxrfKb2C0xs#t9DN@5o0SLc`=-`@})Ut zT=Z~T#`7uJzne52*8*YZbeETw38Dfbp+w!=jI*u;jLo%~iW4Ssia(I=Td} e*2#_Ly#EK=nfk_pxD|W=0000Px|PDw;TRCr$Pn|p9v)qTgm_q7kLB+Ig78(YSfO$h{wnUG>$Hel0)hXaElgV3Q{XNf-h4I&r1gvo`LlYPWa~NfegBb@?pVJsu z%(!C46;mI9amCcfYuv|-D`s3V^${3XOntn@eayIGe$R@T@fYW)OveOdS{vZxGO%qM zRv5$bWB7aeQQX>tx9@xY4_>LG9^mBbKdcI8%tFJgR%DuTa2yAgvS2H~fh~t^*>G%I zz9T3VD};R|^lsRJHP<~f>M_)(h1$*@@t}_Ss|Bj*oH@u$D!`5bD^jqPrC|_+Wy7@` zxV8iNAsB&VL4IrtmggXLfWGd1*!J97tiSu`BOXs})2;oix(CvB^Qo$3@o~tsHv)lz zO&|nefDndfJMb(Q8QX=&BL!q@C>EdqD5VgoSm4B28@)UB;uq)KTlbi1pKk4E)-{Nk z4_vBpCr*VG#9AQ&!-8Wuq7XtLjGXNuXJ?RgGRPP}1jh4|8xl;67=elq#vyzaBC-|2 z46tS8I=puCkLwy+?NhGp%$jdLXT>$jZ7o2RBblBYmZi-_R6-ybG&tGxARvNrEFRi~ zQRfvFK;t=IH5I}Lx#-7dHSb5<$Y93#0)2;oinr?i|^EW6v;{ZVn7$6QT z@f$8&WE~HAJA;CoMWfSzMkj~7lYwV>aBb?uD5b(h)Iu`~RfIqh3gHAO5l$Q+_AK=E z_Tl;Y_tZ4T+NWIGnZw?6_H&;SC|0Pne-JR*gtRZwP@3F4n!E-yIeAe`#`fTvh{T~J zYEj^iHlq}bQ41B598?kE4D|Kkh526{cAT|MxAwE%^M;+zep1;v4`3c*L7uxMj+ScC z4wlLwj0s)=&8}8U*3Q7Sw87DOs&7IlbiJ{PVRtO7AFs>#YY z=-s{ts~3OkeT8$_n;reg70R2@1e9q$fF(WxMlH5P8UiS|IkdP1w0MmINSlzGMxViI z(NL5E+=dLcy}1eh{qVCG*x!fFMRPHI(Fq7L!2Z5olp|lj@LZ?hVaLkf;*DGX?R|qY zd9G?Y|Bnz41gQxSOtr(MsU#-U>NSaC3QitbTMS4PmO9%i1yeDZLKYieS%;t8 z_*Inm_NCvpoir0C+_VT2=g+}FR7SB_6vGqqEqHiw?%ls%FmqPkpi~&^WW!8Qzz7_z zmYg`;ELyw*TD@jWa2t?!vhp3ztyW4hb5Ve6W7o#*c=+nOQQFlzq|r}4>sZXb^=xE5 z*bcwH1jI3H*M)zeh&AWEKPGj^6PSMg$5ifw$xwb|oCE!ehQj}#@6fr5HlvAdBdC}r zw?Xn3<}?SZg`t@~Wk$XobDF22_kXwH)fKDo_)|~d&2?`M3CGEMnEuImX#d2?a2m5v z#Sl&*gLfZ&4V(Yrxg)NeLvAqp#T%6JLmfwK^W5oQL^(|297)=8PDUIpp|ob2&?si) z9b!g01_9@{pMrTU#~Hwy1x;n?(xq6weEDI+MZU8YGj3mm=2JSv--YD>uP^-P_ZQ4j z_k2X<=XIoN5tA@L2#IFI+9z8DW@4rple}hu#3YXyu-29yI}^7BlTH*cF+FKwng+#N zZ@q<6PB}#&4SMm{HB*U9v+rGumNPqHIX1c<`8BrP`{EIWGw9;89$%`gtSgx*Yy(B$ z82`eA&T_@U(roB#TfN3qF?7h)U=qjq=SP1O9l18iTXb}*xaHp7UL1e?@#yO6de0=I zW#KXCTy_xfMW?q1)*@>bU?UyTHR;^lv1q&7on|ZZfbUbF>`4PmW2$pB#_0x`Q zxsZaH^0#NJ!h%_d%XGTBEx`Ot)WT+yd1qaeIA7*04AT=OhoSS$hz}yfBrb)BaBA)t zT+(rdzFyU9_wLb1L|hES33osAD&GCZOGnI{(hGNd?-J!r zYlezqF(a)S3vhH);=h^gvi6}b$x11Zl~SOR+~ttrIVS6sU(b4Y^e?}Kd4*$f^Jj0t zbj)X{8XgVOZm0so zdMcO2?_OPtr*8ij9C&+I-EcZSJ73fi94JZ0FR4hGFcu>p%C%rQ7NUJ6_?z~k>$a!H z1X2ae<4aXk4A3~C5&1#`qBuqvM+l<`QN)%KeUENx6OL^3^DI^&Fm$1$^L}m!awOnF#yK0>$Ke@+poL z$_Nn02264#V`>74Iiep)*D>5z#MY~RS~IAMVwQhGO`miWT+c;dp!fpB9APMfU=5?4 zu#QlixCVCv9j8L1`a4)(6$A*=4(EIdy?EJg`8WvD`!m%r^Q?uHpi}|qCNGN_7 zXh>0jFbEKZ8jMZFIJ!L0OC@YtF~9LlRMM*hR1?2XmrP()p1cgymh1O)?Z%E@Z^FJe zwxGD97c`;Cm(3Ob5z~xKk60AI&jb@i@GaJKb-YaCy6Noi*A8axvp1<3tw*68`qE7! z6rY_nzK02zNWfTT;Y`+w%z6>w5R@#LFgqp~v!tREK3#~)jHZp1b@u)zUcy#d1ly^lU9AV0_<4;QNT8 z7}wUYv7n~6Tc!#2_q=a z!iI%I`-zV4UZU)_2Dr^xakf(TxenNoWJ$6Ar)#n6A78E=%*WT>qe=rs?O(XQ6H+lg z%7G8xFC!=ih(q1Ar}Je}rNNkYX=dpPJdHtVpV$>yw;F!a#R?>1bDAOP}EeYK!O?pu#aT^51I9(Hg1WXu-IfXm>utb>7J+4Gg49rCKdzQ4G}*l|v1NzaV*mmZ+E%O^d)7eWY~Iz9eZ#B}*?N zYqJa^-zRmMaRrHX#H37ER^n`9C_>>o0S$!Mdd;Ip9?ZEv|Gdh#H){wIk&G$Pgcy;i z78Y>y30$T%U?dF}C>n?;DXGd6XKRLEy_7O&6+z&b2Pgj0;Ng4BgD~iHnd`@5M$xVT zI4wDBz4oyq2FE&o%^iw^37D&J9oc{p-$GD+fXEMZADHQN#1$~@SME&qC zFFCs7pins)453KC**$=`--p{?fHN^)m#?YEw5)}{x?M>g!3B0^ zy#&LgF7S1>>xYO5B+xYn-xEJG2vE}066I7iy37iLRz;OGD!uN?c&nnTr20w7O(2yb z1Y3Gw7cv6Hol-zF;A6|>|2pQ%vCe$yi;_|$)il9~dV&xkp#)kjG$B>ep9M^6K8a$g zfE)tnAZ66@=nND|Ma*aaogNv3Gbu0q8D~NcZhHfYYr3%gwiROv$NKQ9+mxi|F%Oe! zGc6CQltM5eou2kJLz$7RDkQ!q`D{9YY4giiRxMnrfzTYo?mh(D_G=(5IXP?|%*2~A z*l_B1#um&;FMK)$!|GY;5Jmu+4uKdmVm2A~`PvB|q82VXRs78$Q%a(gS))n|rs3#F z_Qwp^LVUnS`OTeDmD>}kl&pp`AqOt^Ft-Y}AHbF?$Ihgz2(I8UiYoZbVokBUBYLX~*$n&lK4?13m$x@}IwL4`iiamiavI2x^ahfs$ zM!Z+v!^YFUJ7%h}j(O%fiAr+N$w|&o1%|$b3;bb>aBoo>2dUXGG97F_295@#_s7WR zYQ+pS{Ir(RThXWjK8Vt9b|da9!)eNj$q1BY1BYPPf+d)oi-BKl!Mk60W=!B%ohz=9 z4J$e{ngWb!5g__q;%68m+E>&`UgA3rh9W9TavGzagZxag9$wi^bkNQsmJvA@#sBHT z&bwDyEtejzyv~V$=ZHcG#cs;NY0klJBp9<;Wm{0?5O06 z!lz9+cisA=)pFHbl{;yQ03$4&)afj^qM}Nom;9e>tTM|UsUxoDk!%}b(HAN7KC=Nm z55JyHaMGtwRm@wgybC7*L$x$ifuS%PJZv~^Y|P1;`Ph|8%5_P%H5BZHow){C8Y z4&LHE`LE|IJ~gRWWqE}v;m8I%;RIZg5(WU;(qFLr!+=q(;o?^>h? zMsgUM71fe=Q&WY6-bGWG5dhLf)!@^lQ>En)0rtZdhr#{Fm@1`r8gr0RpnbFRElsE3h-UrsyJO*xo z%N*Szj+SO~2pA5QW*sW{n|rYB`jIc;);y@808PLDVhQz9DYFgX+S(MQpP=&)iA?6j zwn1_AHthRR#eWQ!&QyQj`k8sEa9W4lhlw2lF?t>HqTe&iC&4@WvE}O8mrasujS9@v zI~FRpqe+rMX~9*OLutNZyew-b&%w4EM*b9e`58aHTuIlE{>3DB?**6VFq*!z_(yfk zwXTzg8bHT`OOzU*pAng)i(>l1=JLsQlDvz7*SoRjYs0q|4>#Ev4=s@vtU$>++W8JM z3#y9AYAwCqF;NUJGX2{ZixXy;)eW12rj#UhY%oC9$+&4w$GiR8vbOOL?^wBTm{GUVZ_Gk$oPlI4ozs6NTSNy9j-QMD!8 zzjT&rJa3LpFbRe!L%$DhkwZB|`L}z}eNf(2kAojGQxbFfr^U)?Ymfp{JK<{8RQB`n z=`zdSdiCh~wKE=EqL__uzomX9)Cy^A6!U{i6)Rs2MnlnSUEGW~I4Z^cWo*6nXJc~T zS|>S@^TuR=+;k*07HclEWGaPe5|>)>X=50ZO2W3;-^Vc9|MC{>{L10WjS&xK41aOdieX;i9X&xB zOo|n9&tvPb=j*FSeg83JG3ZjG9+>>43OjvOCS>+*9O8r1l>)~Ci@}XG>{B^X6Cdun zqXIMKu0^V8(Hz7@KTYfeP_=3X#lOT619rwm*nI$-ulU3CH=_bGYxz}*OBw0kHYI6q zWwYGi5+S*pyj!}lG=_cJ;Z#u1_oD(c`-SVxrfKb2C0xs#t9DN@5o0SLc`=-`@})Ut zT=Z~T#`7uJzne52*8*YZbeETw38Dfbp+w!=jI*u;jLo%~iW4Ssia(I=Td} e*2#_Ly#EK=nfk_pxD|W=0000g({qyUPPd5*n`}iDo3bPB8WR+EMMVJ> zWJeGe5O6`!pdiMWXe93Y8jV}xf*boLs3^E6-I;X94>KR;+nhOP&Y8|L&;Pmi7DYiC zAs9{M<~+w#SrqsEz5i#uuid(JU0qk#)pd1UU02uDb#+}`SJ%~bbzNOo*VT1(UB8;k zGHxI_ZWvFl`$Ng|Y&3aaiYMR83FP~A0{NYeCC@!! zUP1$Ir&2&&Dh;kpqoK9wG@>?>M%68+z}s0g=I&}5*SMC(vIW+xpn#(>zdcB{n{q~U@8_;K*eGjT)BjXRV}6WYBDMC<_Zd`&7ui)*)-|a8k%xzEls)o zAx*uLL&1%?H05C~1(s%zYv$NrHzezv(d1ehPyKEtQ@`^0#2JevMEp8+lVb;5BvH-}tr zCXriN0;?sF`U6T?GWnLLP(bBk8pX5xN+z?bV3E=HKB4)I1+?hFPD*{ao0dM>L+Ow98V#=(KiowN9&8st^B7<_ zgPd_^y}%i9Vd1L{r&r1la;{1s=kj=RE{PL2LTu?@3KvQy|B6MTl+g?&_;wD>y}L;k zy7=Kv0kG`xep>PPAgz3Ih_X~$@#G*ae|$jx9&nQHe@=0YTPWi0$KqP}p2>~t=>5|4 zR~L?g$7lniu)jzz$M@&X{-!2%;&c(<%JHCJKI-M`P-;=!2T& zqQ=qpv&sFF=`SCS?Ve!LvkN&DM=N01#Fa|pB)-6n{JCZsuBrubC53}%Cc6*Zq%|m- zWZXk}d1_keBeS3r!-z=ba94%V~V`_iyZ%wYblW96w(aAm5b=b7wAiH+MN!~B$5@cxJ2 z9HW!}Q9(Bz*U-7sXDKf)k90a+n}Gh*&yw8tgwnveG#Y#_gKSerz8pCE$~e+pn@76q z^NeszgKvKhyvRnVaL3fHq_8_1INcUd=A(T|YR1M5AXB_$8NhQDPMdZ%y zh~43~gR#TOP$hvNUUG(YD&bA8h$TZ!0(Br8MUw7HWHUH=h6OMv?htsQ;fmu?cZOb|NHTuVy%JMy?gg_fpOV0lYDCzOE&ZN<`7f8d3;E#=xMFJ25&|QvD$_l81 zftkZFw|1)rBpokBC~&SuDqwE#7Zt@wRzmPaj6v{4oiUx8#Taf9mps_T)$RdRHHtf} z;y|49?FoAJzyC$8T|0N~d@i;03G*S}`cwe|Lo4FK>eZPpR&|xOfS7*X;Z*4J!+{I| z2Rk4Ei&f)vU2!MG7*xH;N&_pG(5UK6X&TYvEV#d&RkN3tKS6=ll%2A_J4PYd@pNea zLHhph-_sAzo>5s@IYmZBQuprNp9_qBOECG?Ep7$|9lox(9U#oziIvuOUvN9Xd^MX) z;W%AY!LVvvisPhDQtFsRQh1H4T_ycZe8X1hq>;8)sLILy<|wWH<_KAOILZRw{`1?^ zqeqYD1_FCa-;2CU8AfFad2xKx;9!F~421)*zO0?oLx*$WBycV;9F8|mR~XDS26G)? zVwI_#8i0|RP|KjmgK82Rwh5f250$Pui{s5Ifbns9ZV={XlQ@L@>(i9j!g0o{Oaars ze17{}2gaXAP)6+RP=TkwVK5gMjH()dG2Doe?%G4`l?HP4JF+^1#@A*`5T18;vjpN4 zb}LlE8LXaF-yNlC`j}w z4yVIN;G9=nO2>iNi8GX5RgG&=lRGK1m^2w|Pp(@_p`5xgI*8+7oYYuA3m@!|puGIM z!<2MuD-F$>Nj>}7QujB0_gr8sX8BOS-K8AUQjFOM=E>BPt<>$2o zUxt#ynK05^N~gvey{a0QB6cSe)nIxzyegejcb1F`X4U6OQ;7*)9LF6@@lXIRdc2EL z|9w9tKip0;PGyo;QV_lCZAbt1m$zDl^2Xb5lE)X3gsIvJ{5j zVR!OrPW?yXUVs#H?^ChZ#;p|pq=4f7`Z>*M*hEuqWYN$a^T>6{7_y$~O+5k}s8^61 zx$h380Pc@a8u&C*i=r5}D=}nKFj?Y-;bwvqZGfb?jN|!Eo*Ubrm_>kNcZ&Z!6DqOB zs2UE$hHKH}%&KuKNl>2falH-44kgTovyNKuE$8~R%SEGlLCPw&y&*WeJ=da zE=;IhO_MnG0Mb;>T*0d0{}GcW)UAw zzigM?_sDb#xRy*~>sHZ-nhY68;bst9kezg@OF649rOki6w8toTwp6J+TaxJ;D+uvt zECbLihz;!oQaxrm_$&tMsHTzWFfs*b)1V9Y5h%P#?v;sTlQ-s<1><`$fu`55mjz&+ zi<|V|4B)~boC@a|V~*xhuEp`jXG~t|;}k3k3j`np=8;?>zXz+yWDv@qcn=Bz5U2!d z!|)3mfrod#KLG_<5x=+ZmWjVCm}$4x(bU^H;tC2FR!m7EIWq{SixEmdJ~x}=O_T~p zaVx|eRHImcC#y#T1O;KyPy;}TF^Iucsr-Jbv=#s|K%i(!QJO_h6DaN~6a%|5?!)fj zG_u_rOjheh|1y9=@8)w{SR;Oq=g-)^{zV*P3Zoww?k*1;Rh;#^2?_!QQ}|;B+BEHplMJbh6$UM16No zA^YPq!#FCx#P`Q%#2ZuHe$vi~xSv~-SI2RkP>#WyT~ z;9d*~Zs&ZBAzh2*Ma9Z)yWNPBMYV2C}p?)YretL;j(z!eZhP)lQ`&2B|MaC z0>lbBrT_v!?5wDWvll=)GFa)>RnvWC`g(S=zY_xt{#i{WvMFq~yQfm`#Y4zq`AEf; z_+IRfwgiLLKzBW=bHN}m!vEc_#;7hdTW-qk;B?sqo6jb42ACu=Mpi(|GzA1{qbwH{ zol3Q!Ek|x`>@l%TrmNIneNSm z&IN<~rh#`n8HlI!)>rG=h@QqUdZEFIAoiqYsfQSRQVR17Rk}Oc&c~O-H ztre5cXh8To0166uH`tBu?Nf5dP$k0a|($CJ%g6%gEuGlT%*o3TA$3P@Fv21x_emf>^9Lj($%#J7X= z)HB|ndM_HRC?;10!zzW_378vE&4=Sfo#;+Zg({RYY8K!{S@KO-t_xJ)@Xn!z5cO<^ zdd9bOuRZ2~R5v@SC<)&wurxc~+~n_%Do_BS+3Bvh0P4MTm{P|8%;6c5##?|c#DG3FQ_oKUI-tfOs0eoCUl;?#rkF!9 zy(}_^DKX~I42etfM8gb>%!D}zaxj1aY0=6ujxJpyN}6kRRg zXzqphvrmmdnu=hDOiTp^1tI?QN(^XoAr{&1DKSXEM6?7WaAJ&)X=Q+QaW3EUxDE`% zkqy{qt@46e{BW;%J_5ta+_g;MXs*RFN1XvUM)jBgGOEZ#O;Qr>(C1Z5NDG=n1)y3EZ=)OyK=bE^L`d}1z=bq5a%Nxk5kjRq8gh5HDhTp z2X3Xo;Xk1gTP_xRCk^Vb|GyjUqdom#{XG)~bdEcrg7P!9z8+vS)!0kF)3VezHk2sL z(4?{pyf$ED(4-BRPMUPg>gYjxHjZN^h)J&nls@UhBxTB}tgmJ(qsepOMw5x2dN2uf zhuyB=*8_~4r@>j_tLn*5tt!2wn)bR-ITh-7IpXyIgOQ@t6ezUN?Q&y>`Kug_H8-3H z#eBB#Hx35{o}5!L?^TL4i!w9yA97U3%V6p^3kH2jyAKR%)3&-q>hq$WBEHNE;|Hxj z>5z5yjP{iYx*R7AHOiC>=V*=in}TFSfkT9^^4k6%W;Th}XY2#u00000 LNkvXXu0mjfJZkoY literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch18.png b/examples/moving-saw-platformer/assets/Punch18.png new file mode 100644 index 0000000000000000000000000000000000000000..b3b27c250a6a68aa8c476757d3cfbe7209970833 GIT binary patch literal 4733 zcmV-@5`yiCP)g({qyUPPd5*n`}iDo3bPB8WR+EMMVJ> zWJeGe5O6`!pdiMWXe93Y8jV}xf*boLs3^E6-I;X94>KR;+nhOP&Y8|L&;Pmi7DYiC zAs9{M<~+w#SrqsEz5i#uuid(JU0qk#)pd1UU02uDb#+}`SJ%~bbzNOo*VT1(UB8;k zGHxI_ZWvFl`$Ng|Y&3aaiYMR83FP~A0{NYeCC@!! zUP1$Ir&2&&Dh;kpqoK9wG@>?>M%68+z}s0g=I&}5*SMC(vIW+xpn#(>zdcB{n{q~U@8_;K*eGjT)BjXRV}6WYBDMC<_Zd`&7ui)*)-|a8k%xzEls)o zAx*uLL&1%?H05C~1(s%zYv$NrHzezv(d1ehPyKEtQ@`^0#2JevMEp8+lVb;5BvH-}tr zCXriN0;?sF`U6T?GWnLLP(bBk8pX5xN+z?bV3E=HKB4)I1+?hFPD*{ao0dM>L+Ow98V#=(KiowN9&8st^B7<_ zgPd_^y}%i9Vd1L{r&r1la;{1s=kj=RE{PL2LTu?@3KvQy|B6MTl+g?&_;wD>y}L;k zy7=Kv0kG`xep>PPAgz3Ih_X~$@#G*ae|$jx9&nQHe@=0YTPWi0$KqP}p2>~t=>5|4 zR~L?g$7lniu)jzz$M@&X{-!2%;&c(<%JHCJKI-M`P-;=!2T& zqQ=qpv&sFF=`SCS?Ve!LvkN&DM=N01#Fa|pB)-6n{JCZsuBrubC53}%Cc6*Zq%|m- zWZXk}d1_keBeS3r!-z=ba94%V~V`_iyZ%wYblW96w(aAm5b=b7wAiH+MN!~B$5@cxJ2 z9HW!}Q9(Bz*U-7sXDKf)k90a+n}Gh*&yw8tgwnveG#Y#_gKSerz8pCE$~e+pn@76q z^NeszgKvKhyvRnVaL3fHq_8_1INcUd=A(T|YR1M5AXB_$8NhQDPMdZ%y zh~43~gR#TOP$hvNUUG(YD&bA8h$TZ!0(Br8MUw7HWHUH=h6OMv?htsQ;fmu?cZOb|NHTuVy%JMy?gg_fpOV0lYDCzOE&ZN<`7f8d3;E#=xMFJ25&|QvD$_l81 zftkZFw|1)rBpokBC~&SuDqwE#7Zt@wRzmPaj6v{4oiUx8#Taf9mps_T)$RdRHHtf} z;y|49?FoAJzyC$8T|0N~d@i;03G*S}`cwe|Lo4FK>eZPpR&|xOfS7*X;Z*4J!+{I| z2Rk4Ei&f)vU2!MG7*xH;N&_pG(5UK6X&TYvEV#d&RkN3tKS6=ll%2A_J4PYd@pNea zLHhph-_sAzo>5s@IYmZBQuprNp9_qBOECG?Ep7$|9lox(9U#oziIvuOUvN9Xd^MX) z;W%AY!LVvvisPhDQtFsRQh1H4T_ycZe8X1hq>;8)sLILy<|wWH<_KAOILZRw{`1?^ zqeqYD1_FCa-;2CU8AfFad2xKx;9!F~421)*zO0?oLx*$WBycV;9F8|mR~XDS26G)? zVwI_#8i0|RP|KjmgK82Rwh5f250$Pui{s5Ifbns9ZV={XlQ@L@>(i9j!g0o{Oaars ze17{}2gaXAP)6+RP=TkwVK5gMjH()dG2Doe?%G4`l?HP4JF+^1#@A*`5T18;vjpN4 zb}LlE8LXaF-yNlC`j}w z4yVIN;G9=nO2>iNi8GX5RgG&=lRGK1m^2w|Pp(@_p`5xgI*8+7oYYuA3m@!|puGIM z!<2MuD-F$>Nj>}7QujB0_gr8sX8BOS-K8AUQjFOM=E>BPt<>$2o zUxt#ynK05^N~gvey{a0QB6cSe)nIxzyegejcb1F`X4U6OQ;7*)9LF6@@lXIRdc2EL z|9w9tKip0;PGyo;QV_lCZAbt1m$zDl^2Xb5lE)X3gsIvJ{5j zVR!OrPW?yXUVs#H?^ChZ#;p|pq=4f7`Z>*M*hEuqWYN$a^T>6{7_y$~O+5k}s8^61 zx$h380Pc@a8u&C*i=r5}D=}nKFj?Y-;bwvqZGfb?jN|!Eo*Ubrm_>kNcZ&Z!6DqOB zs2UE$hHKH}%&KuKNl>2falH-44kgTovyNKuE$8~R%SEGlLCPw&y&*WeJ=da zE=;IhO_MnG0Mb;>T*0d0{}GcW)UAw zzigM?_sDb#xRy*~>sHZ-nhY68;bst9kezg@OF649rOki6w8toTwp6J+TaxJ;D+uvt zECbLihz;!oQaxrm_$&tMsHTzWFfs*b)1V9Y5h%P#?v;sTlQ-s<1><`$fu`55mjz&+ zi<|V|4B)~boC@a|V~*xhuEp`jXG~t|;}k3k3j`np=8;?>zXz+yWDv@qcn=Bz5U2!d z!|)3mfrod#KLG_<5x=+ZmWjVCm}$4x(bU^H;tC2FR!m7EIWq{SixEmdJ~x}=O_T~p zaVx|eRHImcC#y#T1O;KyPy;}TF^Iucsr-Jbv=#s|K%i(!QJO_h6DaN~6a%|5?!)fj zG_u_rOjheh|1y9=@8)w{SR;Oq=g-)^{zV*P3Zoww?k*1;Rh;#^2?_!QQ}|;B+BEHplMJbh6$UM16No zA^YPq!#FCx#P`Q%#2ZuHe$vi~xSv~-SI2RkP>#WyT~ z;9d*~Zs&ZBAzh2*Ma9Z)yWNPBMYV2C}p?)YretL;j(z!eZhP)lQ`&2B|MaC z0>lbBrT_v!?5wDWvll=)GFa)>RnvWC`g(S=zY_xt{#i{WvMFq~yQfm`#Y4zq`AEf; z_+IRfwgiLLKzBW=bHN}m!vEc_#;7hdTW-qk;B?sqo6jb42ACu=Mpi(|GzA1{qbwH{ zol3Q!Ek|x`>@l%TrmNIneNSm z&IN<~rh#`n8HlI!)>rG=h@QqUdZEFIAoiqYsfQSRQVR17Rk}Oc&c~O-H ztre5cXh8To0166uH`tBu?Nf5dP$k0a|($CJ%g6%gEuGlT%*o3TA$3P@Fv21x_emf>^9Lj($%#J7X= z)HB|ndM_HRC?;10!zzW_378vE&4=Sfo#;+Zg({RYY8K!{S@KO-t_xJ)@Xn!z5cO<^ zdd9bOuRZ2~R5v@SC<)&wurxc~+~n_%Do_BS+3Bvh0P4MTm{P|8%;6c5##?|c#DG3FQ_oKUI-tfOs0eoCUl;?#rkF!9 zy(}_^DKX~I42etfM8gb>%!D}zaxj1aY0=6ujxJpyN}6kRRg zXzqphvrmmdnu=hDOiTp^1tI?QN(^XoAr{&1DKSXEM6?7WaAJ&)X=Q+QaW3EUxDE`% zkqy{qt@46e{BW;%J_5ta+_g;MXs*RFN1XvUM)jBgGOEZ#O;Qr>(C1Z5NDG=n1)y3EZ=)OyK=bE^L`d}1z=bq5a%Nxk5kjRq8gh5HDhTp z2X3Xo;Xk1gTP_xRCk^Vb|GyjUqdom#{XG)~bdEcrg7P!9z8+vS)!0kF)3VezHk2sL z(4?{pyf$ED(4-BRPMUPg>gYjxHjZN^h)J&nls@UhBxTB}tgmJ(qsepOMw5x2dN2uf zhuyB=*8_~4r@>j_tLn*5tt!2wn)bR-ITh-7IpXyIgOQ@t6ezUN?Q&y>`Kug_H8-3H z#eBB#Hx35{o}5!L?^TL4i!w9yA97U3%V6p^3kH2jyAKR%)3&-q>hq$WBEHNE;|Hxj z>5z5yjP{iYx*R7AHOiC>=V*=in}TFSfkT9^^4k6%W;Th}XY2#u00000 LNkvXXu0mjfJZkoY literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch19.png b/examples/moving-saw-platformer/assets/Punch19.png new file mode 100644 index 0000000000000000000000000000000000000000..b3b27c250a6a68aa8c476757d3cfbe7209970833 GIT binary patch literal 4733 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 LNkvXXu0mjfJZkoY literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch20.png b/examples/moving-saw-platformer/assets/Punch20.png new file mode 100644 index 0000000000000000000000000000000000000000..bfa604e661acfe71699ecd6de03899d98455ddaa GIT binary patch literal 4568 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch24.png b/examples/moving-saw-platformer/assets/Punch24.png new file mode 100644 index 0000000000000000000000000000000000000000..09ca23525c5529bccab72e2bf4d7e511b4348cf4 GIT binary patch literal 4334 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch25.png b/examples/moving-saw-platformer/assets/Punch25.png new file mode 100644 index 0000000000000000000000000000000000000000..09ca23525c5529bccab72e2bf4d7e511b4348cf4 GIT binary patch literal 4334 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Punch26.png b/examples/moving-saw-platformer/assets/Punch26.png new file mode 100644 index 0000000000000000000000000000000000000000..09ca23525c5529bccab72e2bf4d7e511b4348cf4 GIT binary patch literal 4334 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Run29.png b/examples/moving-saw-platformer/assets/Run29.png new file mode 100644 index 0000000000000000000000000000000000000000..f0ff62028db6371d2ff3f44e98646cbea8b65d8f GIT binary patch literal 4502 zcmV;H5ozv;P)WZ#NS1jHp#P@@u;;0l5o z4I*0s3Pcta1wo9F5KW>c?k0*$o5jR*YeG~+76AcSL|kIheY&Sl&-^v#%*;7GnKNfP z-nrlV-m7|5fTp{(QnBlK?x~`xc+~s6?_GaC2Mux@j>B;{4#(j*9Eam@9FD_rI1b0* zI2?!La2$@~ANlaAoJ~Q;mQvVfDHL%ogT~aXq|wz`H1IRzLxshh|Y@!!$Y^Isr zr8KEJmjX&+9xX_&<8sC&hQOyPPe9KyjZe33^ zT8k;By_Dv(Z=!iu%W3}A&9tE7Rf@f~g<@}3(Cn^FG+FeO6cWN{VRArm+GADp@BAfhrbv zRtSXDo*iVozKgPY-=&qkyG@pP{as4CzLQp5dy|%SRZ;>2T6nvXp08g0H{WItAAo8B8XHHe`tljlG;p6PojB>XjmjX)C3K&aITh7Yi6UH}+EA%>z_$^AHu@ zIz(%3y(fm}cpdL&^}a(XJ#VvuwoyXIR*Jj6m1ee<*gqV<^T`z0l1Tw|X$;25U=+24 zv0C6l|eT0f{S5e7VN5zW2s-pG$+S*(1Q~u3^ z^4ScAxZ>Jd^b-GmT*nrg-~B4Z^px8#9KQ?63Cq)Gl%Nc7nt8W&ccV@>%n%1$we&Bc(jeVjNTy&`p$fi3d#LC2!*EXtf0I`r`P7eQWde1Hn!f((5J|CbU)lXv= zjqWO;3FmTucsS3bj8&nei0Q!~@WPD{TOwI4Gunzd`@Al$0JkXCLD7Kd%^D6qk2nO? zWU*?NbI^|KdX3LpA})&551Z0cLjGIl{;+U- ueJc6YT7ywC5`r!=5xy`2?s87a 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Run32.png b/examples/moving-saw-platformer/assets/Run32.png new file mode 100644 index 0000000000000000000000000000000000000000..58793903b8a87eca6570512d69906a14ad71dd14 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Run33.png b/examples/moving-saw-platformer/assets/Run33.png new file mode 100644 index 0000000000000000000000000000000000000000..cf6c13069cea900dcf256fcc360fb6650fe5f125 GIT binary patch literal 4377 zcmV+!5$5iRP)A8i`GNCJ(_fMqu6*H()bq000ltEoD z%%tvR8Pwy#Eb4t>4)racN5K`@H0WXug;Xx2(CQ@=R=b>r-^it5waX~zXd0Q)2RuKJ z{EkndcGYRrt~`}GluoBk=Thn2bLrImdK{F^#BNMkA}1Q)G26 zjn<^%QMIdSbln>2`%U_@2gko8 zfdVU1D6lw*p(Il~fij(;%%E=PXL9Pyr2!T5DXelajj3KK2OWQPBTc*Z5v5+=N@+K? zQMw^!T>qGVw^^POedT=`cX>69xwe`{Tw6hbIYXX)KyPREp@6FC6mTwy0*Vvq9fs1D z)uN}64h23E!6`HG@>)u``XL|qR+@G5Q<{5g2W8#Lr|eswQ+Az-%({GUh=`)a(0uPC< zeV^wS5YWm-@2uS_9xaXk5PKrJebrb!xg<`n8tHcL!4ymFbO!*o9TP=XF*@$KEV zac8%{S#W!&JZB!OY37YjD1}oBU?vEdTmdtTO*{0)a%#UZ>gj^xcQKjFCGlh~Qegax z*<(tSVmh3gPVcf>P<=u#Eu!&kpzxA833B4m&nGaHsT!CB3mEtdyyZPs3(OV=5_fe2 zW$>AY3IJt^24(4;JvL#5vs+6ks3u=jlf+;rv0;zo_Z!Mk2Cx$QS7cG}rTN?(W<7Z@ zuDOERHzE|c`|LY5>*!PvmLy<1W$NAnuIM?6=jv0Ryk)hwZYS8}NHms2S)cLa6XJB9jwzlgkM zKB1Iy|0IHZ&n1v=VH|^rv#3T-C6wxpl13S9x>=G&@CH;Nc*}#-Qa`0EM$E6vMz++ zT9dAB64PDqkTkOIHM=MaeGP-j`||->^V31fy1JcwgF6b4`r$h9U2;zidc1I4^M*(j zGM$dK!eP~z8IE6(4klTZX&w>>YG4wtX<+IKLh3M3d>;7%LntrTosS z1`mqq#EN_3ouSpmxY@7s(5f!LJza^=RyH+m(}ts$36LDU3>TLwF?IE z;%hHE9!|@7y~+2xIPy6**$U^Brkd{nW-9p?sj8%#FQ(|>+=yXVoPG@*?+(i0j&{)< zTR661@D}!!f`1fgYGE)M79*Ja{QL&Nh;kea$9+>6`7jKhqmvDAV#)WE0%K;?0F2)C zqFndk!ExxtMN(cd1ZLd$R7@1@{-TDuUQ3zg&iJqUX#BQ0R9#g~_SW6IcPThH*gljd z`ePIN!&@yJ2dDMkDDq~H@jfz%e7@1)#3(Rl7!1SlKdZ`h`%*Oy^eUUp2Ao5qs#fr1 zyk1lz!(*KeXO{wD3=PVXANSCVvW?X2jTYqX)tU}}eVG3J%P$rvH*emgh=_;>szr~c zEnadQ81JvfllS3?Ds(tJ7WhInr?qq{jHh>ah{OP?duPQj$Mo8i^4i%;I90X$q5R_+l zOV$rNDdu!8HGA{bMgy=LO`AB@W1y7QUyUR0KiR^;FzL$`%FL=Uf5!%_sRrqUvW-SB z=mNGf7fMQDKP9SWmF(bQ;+}MQ9miTpHGsmf2t}n|-$off?x3ODr&H5cn*C-lO<#G@ z!C($fpw|1x*}~CM%A%UnoK6fUut@bY9kKOrE?xFy`g2NQ(_8jX*pN}iv9A(Uy^6-y zfzPo`lcOr2%DG6jGiefWo+(kEmQGpr9yqm0+bP zDvCitU1RIk(V%bV(CeK%8x7@U(;JVc!SmWZhP?JMn0*S4nDId^rF7Mt)KwF&sU}(5 z_njf-8)n?KkjI50_MTEsF^1HyER%v+P1yRxr4(E}z*Ys6rJya92(4X8!56aVo!LXk zHKZNA*2a~~@T=6cc{ANdY#KY?onsvjrq%p@l0E{5%eKHdVDuXpakRj(s)oI$D9N%Z zj`^u`Nh-DbHi0^v;z9Eaj}C>LYG-Fq*OD~qUYai8aLoyZ9aKI~_FIsG7)A$i*&kB5 zh(fO~r=i!E(SXVv>Qk6O-M(h{d-$ZR9ZqiPeW>N+&g8vyB(UJQ40ATi6Q@^9LJ_m!0|W={FXiGR6Mmg z!wM_p^ebX-Dq)bNGvrzn(on8kvQPEobi~HGMEM-*Suuy+yEvP=UYbQ+sxqiU^-OA8 zl}3T()5xzRK~9uoE{n|SMShp2k-0Qpl;QdLDDo;8ZB>pANB0};z+eb2-NLCKVE{3zGURoXIgFQ0YsvOO4 z&=JFP+Ay5JGYQJT_m34ot@U)Q*EkyIF<)r~R0E0k3Mf)nBUB{H@CqQ<6Vjnb6yv*3 zeY9X&Eghitb@dP7A<;8Gk~}|SI6FpZfDG!9Qm!chX$1vXJV*660ousme>z^w+iRZ{ zto~ZPN3tC~qGe7qozws0PMlSNV|cXQ0x%T@Fq}?E9gnRe$m7!pr5+tn zfx&zB8+^x-BC%FL=#J0wS>}>%J{GG0@#`#b8-jFH2Ni7rWdlnCW@2^8CYrX9W-d#7 zv|w;C&95rO3Wie(5_jJ`T*2AK@kxZOf^u)t^^A~=>2@C|4c77K`<11^dGyzg_ya)Pn6qAAM3Vc)VG7U|hVyY_04bw2A;rF7 z1;L;-NCFB~jA03&!#u$s7%x4O*Iun}(i=RZgh!g73gahP*l~DxB*;fye zjiM%4ybW6+YWp=tKF_gtGtBGF5W>i9jk@*X&BX2k#BKdha{C}uDF}c*Y5wGYv}|KdW!Mi^~wg{d-8WVEbLEi?=zUSL)0S!a@#OWspz9H1E2<~ zn88QX0ct5yKMollje(!>Yb3o;`q`gcmJf9BB+Vb}!Kv~<70vBKZh0Z(x^fV?t_e|q z)-j;J1GfFBeGv~<#554E;h+@D-?9duJ8x?8_X$z;Be zM7X#Hx34cz*A;^}eZt6P*+4>B$F*$N)q}~EK_T4)kTJ!!Frbgal}V$_=NkZ_QQRG6 zRgn(rVS(qN%=07Cw$*}uq8KO^pa1BuG%^rN6_QG%1)DIw5Dv_X(*lYBAb^qJFD2?( zr2*1YOgHKJ{-Xgxm6H@J7^6W_O0tCB;}}AICcoqF!>QV8L4R^t989kKnfM$$2Pfju zT?ybfMfI@(Q>37vJ%}4pd9{O z*VQ5P_PikFEBqONj?}?(q*p?3#NQVqjoaGa={HCdGj8v&2S!h)lQGg)cyl`8>_N&% zKPlCK!)Fd^(cwTzFyn?i$6fE7?ZMGYJYc}v`17RlaO$8UB7I!&{;XJ}Ct#vV>DSlg z-W^QazgIOj1EXEl#938yNK*~Gh7U@bzx4`^lyE3T3!GV~MO1>+<7y_QyuNBU4LsO$ zpa>YTnCzZ0qOdn6byAIGayK#AR*QlKiZWZ}D{?`Qn?QJ>OxN1?Mlrz&`E48BELEGC zs4=SfN^Ny|?ii_33S|;-kTTNv-T!4;&gm`E2N)>C!%(_CISnK|8J5fPLG(s!7qWl* zY(I+v@jg(k_zFgX6Do!DJH3npFn06cP3|9rHXf2dDW3XpFuK>Ah?dq|reT)22d4mr zHBkbBeaE5K(eWARuD2;)L8bKhMoS@sT5MX5(s=31q(3W7kUr=k8&bj4P#OW4AD3_O zo|5?cD-;Gi?j>N3=qDttHibQwdBsZ`G0YQzb~u>lf?+XoG#nV4>A!hM7R z%Y#kLmCG;A2sVHK$9y4C-BkrRT1x4D0QEesS?#U#o@(0xgD9?RosMlZ6l3^bNhOz6 zcE*VMYJocNGf%Dn_HQ>EOkP|$n_(;OIWextzA8i`GNCJ(_fMqu6*H()bq000ltEoD z%%tvR8Pwy#Eb4t>4)racN5K`@H0WXug;Xx2(CQ@=R=b>r-^it5waX~zXd0Q)2RuKJ z{EkndcGYRrt~`}GluoBk=Thn2bLrImdK{F^#BNMkA}1Q)G26 zjn<^%QMIdSbln>2`%U_@2gko8 zfdVU1D6lw*p(Il~fij(;%%E=PXL9Pyr2!T5DXelajj3KK2OWQPBTc*Z5v5+=N@+K? zQMw^!T>qGVw^^POedT=`cX>69xwe`{Tw6hbIYXX)KyPREp@6FC6mTwy0*Vvq9fs1D z)uN}64h23E!6`HG@>)u``XL|qR+@G5Q<{5g2W8#Lr|eswQ+Az-%({GUh=`)a(0uPC< zeV^wS5YWm-@2uS_9xaXk5PKrJebrb!xg<`n8tHcL!4ymFbO!*o9TP=XF*@$KEV zac8%{S#W!&JZB!OY37YjD1}oBU?vEdTmdtTO*{0)a%#UZ>gj^xcQKjFCGlh~Qegax z*<(tSVmh3gPVcf>P<=u#Eu!&kpzxA833B4m&nGaHsT!CB3mEtdyyZPs3(OV=5_fe2 zW$>AY3IJt^24(4;JvL#5vs+6ks3u=jlf+;rv0;zo_Z!Mk2Cx$QS7cG}rTN?(W<7Z@ zuDOERHzE|c`|LY5>*!PvmLy<1W$NAnuIM?6=jv0Ryk)hwZYS8}NHms2S)cLa6XJB9jwzlgkM zKB1Iy|0IHZ&n1v=VH|^rv#3T-C6wxpl13S9x>=G&@CH;Nc*}#-Qa`0EM$E6vMz++ zT9dAB64PDqkTkOIHM=MaeGP-j`||->^V31fy1JcwgF6b4`r$h9U2;zidc1I4^M*(j zGM$dK!eP~z8IE6(4klTZX&w>>YG4wtX<+IKLh3M3d>;7%LntrTosS z1`mqq#EN_3ouSpmxY@7s(5f!LJza^=RyH+m(}ts$36LDU3>TLwF?IE z;%hHE9!|@7y~+2xIPy6**$U^Brkd{nW-9p?sj8%#FQ(|>+=yXVoPG@*?+(i0j&{)< zTR661@D}!!f`1fgYGE)M79*Ja{QL&Nh;kea$9+>6`7jKhqmvDAV#)WE0%K;?0F2)C zqFndk!ExxtMN(cd1ZLd$R7@1@{-TDuUQ3zg&iJqUX#BQ0R9#g~_SW6IcPThH*gljd z`ePIN!&@yJ2dDMkDDq~H@jfz%e7@1)#3(Rl7!1SlKdZ`h`%*Oy^eUUp2Ao5qs#fr1 zyk1lz!(*KeXO{wD3=PVXANSCVvW?X2jTYqX)tU}}eVG3J%P$rvH*emgh=_;>szr~c zEnadQ81JvfllS3?Ds(tJ7WhInr?qq{jHh>ah{OP?duPQj$Mo8i^4i%;I90X$q5R_+l zOV$rNDdu!8HGA{bMgy=LO`AB@W1y7QUyUR0KiR^;FzL$`%FL=Uf5!%_sRrqUvW-SB z=mNGf7fMQDKP9SWmF(bQ;+}MQ9miTpHGsmf2t}n|-$off?x3ODr&H5cn*C-lO<#G@ z!C($fpw|1x*}~CM%A%UnoK6fUut@bY9kKOrE?xFy`g2NQ(_8jX*pN}iv9A(Uy^6-y zfzPo`lcOr2%DG6jGiefWo+(kEmQGpr9yqm0+bP zDvCitU1RIk(V%bV(CeK%8x7@U(;JVc!SmWZhP?JMn0*S4nDId^rF7Mt)KwF&sU}(5 z_njf-8)n?KkjI50_MTEsF^1HyER%v+P1yRxr4(E}z*Ys6rJya92(4X8!56aVo!LXk zHKZNA*2a~~@T=6cc{ANdY#KY?onsvjrq%p@l0E{5%eKHdVDuXpakRj(s)oI$D9N%Z zj`^u`Nh-DbHi0^v;z9Eaj}C>LYG-Fq*OD~qUYai8aLoyZ9aKI~_FIsG7)A$i*&kB5 zh(fO~r=i!E(SXVv>Qk6O-M(h{d-$ZR9ZqiPeW>N+&g8vyB(UJQ40ATi6Q@^9LJ_m!0|W={FXiGR6Mmg z!wM_p^ebX-Dq)bNGvrzn(on8kvQPEobi~HGMEM-*Suuy+yEvP=UYbQ+sxqiU^-OA8 zl}3T()5xzRK~9uoE{n|SMShp2k-0Qpl;QdLDDo;8ZB>pANB0};z+eb2-NLCKVE{3zGURoXIgFQ0YsvOO4 z&=JFP+Ay5JGYQJT_m34ot@U)Q*EkyIF<)r~R0E0k3Mf)nBUB{H@CqQ<6Vjnb6yv*3 zeY9X&Eghitb@dP7A<;8Gk~}|SI6FpZfDG!9Qm!chX$1vXJV*660ousme>z^w+iRZ{ zto~ZPN3tC~qGe7qozws0PMlSNV|cXQ0x%T@Fq}?E9gnRe$m7!pr5+tn zfx&zB8+^x-BC%FL=#J0wS>}>%J{GG0@#`#b8-jFH2Ni7rWdlnCW@2^8CYrX9W-d#7 zv|w;C&95rO3Wie(5_jJ`T*2AK@kxZOf^u)t^^A~=>2@C|4c77K`<11^dGyzg_ya)Pn6qAAM3Vc)VG7U|hVyY_04bw2A;rF7 z1;L;-NCFB~jA03&!#u$s7%x4O*Iun}(i=RZgh!g73gahP*l~DxB*;fye zjiM%4ybW6+YWp=tKF_gtGtBGF5W>i9jk@*X&BX2k#BKdha{C}uDF}c*Y5wGYv}|KdW!Mi^~wg{d-8WVEbLEi?=zUSL)0S!a@#OWspz9H1E2<~ zn88QX0ct5yKMollje(!>Yb3o;`q`gcmJf9BB+Vb}!Kv~<70vBKZh0Z(x^fV?t_e|q z)-j;J1GfFBeGv~<#554E;h+@D-?9duJ8x?8_X$z;Be zM7X#Hx34cz*A;^}eZt6P*+4>B$F*$N)q}~EK_T4)kTJ!!Frbgal}V$_=NkZ_QQRG6 zRgn(rVS(qN%=07Cw$*}uq8KO^pa1BuG%^rN6_QG%1)DIw5Dv_X(*lYBAb^qJFD2?( zr2*1YOgHKJ{-Xgxm6H@J7^6W_O0tCB;}}AICcoqF!>QV8L4R^t989kKnfM$$2Pfju zT?ybfMfI@(Q>37vJ%}4pd9{O z*VQ5P_PikFEBqONj?}?(q*p?3#NQVqjoaGa={HCdGj8v&2S!h)lQGg)cyl`8>_N&% zKPlCK!)Fd^(cwTzFyn?i$6fE7?ZMGYJYc}v`17RlaO$8UB7I!&{;XJ}Ct#vV>DSlg z-W^QazgIOj1EXEl#938yNK*~Gh7U@bzx4`^lyE3T3!GV~MO1>+<7y_QyuNBU4LsO$ zpa>YTnCzZ0qOdn6byAIGayK#AR*QlKiZWZ}D{?`Qn?QJ>OxN1?Mlrz&`E48BELEGC zs4=SfN^Ny|?ii_33S|;-kTTNv-T!4;&gm`E2N)>C!%(_CISnK|8J5fPLG(s!7qWl* zY(I+v@jg(k_zFgX6Do!DJH3npFn06cP3|9rHXf2dDW3XpFuK>Ah?dq|reT)22d4mr zHBkbBeaE5K(eWARuD2;)L8bKhMoS@sT5MX5(s=31q(3W7kUr=k8&bj4P#OW4AD3_O zo|5?cD-;Gi?j>N3=qDttHibQwdBsZ`G0YQzb~u>lf?+XoG#nV4>A!hM7R z%Y#kLmCG;A2sVHK$9y4C-BkrRT1x4D0QEesS?#U#o@(0xgD9?RosMlZ6l3^bNhOz6 zcE*VMYJocNGf%Dn_HQ>EOkP|$n_(;OIWextz03~q=hC~9y)K}1Cq zkyT_<1VjZ?T$8$MT%x!nnl@>(XpB)&Ko&(&5HYA}^P$_9p7!)ZbCNGj-oDR!?;Y;o z7)e@2Vz@c~Gcvgh+~0lP=Ux6+`}FBOdXL_t_vk%(kKUvA=skLm-lH22yVMcnw(%7* z?T#kzLviF=F^7B)#L>WAv1D8`nSN9-Ja$LXz;h`ScrAy9-dsk*Z|2j8rhFRJR6wCO zifHW3Vj9=7iXvJ|Y2xitifCRymSCb)70xvJ2AQcK! zGX82YO}<`AF*nKuz=D>ow5WAErL^v(wA;Is)w)Z*PP(;?=C`~?vzs>wpc$WTB>&Ab ze>i~L4n>o1(-QKjPNjj>X*7tTyu@l53@Eh^u7@ z@6G{Q_URkCb&zuTy(Mk03#f$*2;UQXa|1=UZ=#U*GkZQ9&kqyG=h|ZOW+*-kMXwfw z5IhA?Ub$An7q(F@5dE|X1ouQEvItm;!5;(6G8(2_Gm0ev!;7$zg>6 z2w<$fcbrP@y=k#l^ICcDn7~=yen`&GxV?wNYCEguRq>;!>uYIh%Q_0LFY0-4+}?~O zudC@~s!Ap=1_L-67=#hBP;mV+$vU{pxG-E~5i4O8UpOF?-g}G6?su$GUM2V66kt$J zAp^|2bC4Cbmlg?_E%I4Yo7Qj^E1_3f$|$rlujjzAFBwN(*E7giwMYe%Yyl>Ky=7>9 zu7uFE>uV^14HSL>r2q zv6v=u{S$C7zGuLJQjFD$9so12CXG{chIq?JHrxrU7K9Ky0;UQN!9{B@IZd*rTw^q^UmK7AzR7fFLms4=# zW2|!qpRtcXB#cvG4|@V|a!ZJ`aP^0Y~*4)rg@Q zr0?|hy)@_677AP+Lk<%Lk^QunDBxrw1veK`@XbQ<*&XwE;22KN6BwSA3$1`j5ils| zkfOt{t`MV4Wp9u$QoW_CV6fmb@FhUWY=50*SFa<-utB(Z^Lpy%KPBJSXVJ*kA{usW z+2a9Ys!Ju$3k#KXQGsK+)By&@i!_abZXAO_YK6bRKyi^>2XjLFXzl%zbn#}KN1Hcqpg1LMAk^Z7Vfwye^{C)cCSO1{S$L-s<$z(D;00+x0Ka7SnWZM>u=O+uu z^DM7V5-s7dYP_nH0uLD}P|ZjPrD!hyQPd%;6zeil*&~b>*{J>Be-;q``Q~f-`kQYE z|7pkBvuCY>!E!H|U|TQ%U^p|M3?Eylu&9e z=&V6G!SIgLra!zx|NhUH0^@52V~K_6i!Z()H#aw{V1B}3^{Y^$ZQ$5*=WJvMhK~{i zj#)Y98B8UEVL0AZipLB_D=wtsShI1Kj%@=InITqMqs85|sbx9h$N|gJR-h>8r24dcb48{PIhRjEsC} zDCw2c?O@zb&LR(P7(G6S?|{RgjI0_c32?kQoRk7@F}(}}<~|8N6UDVm0;?wN_HL^U zWT^^7GS+7&sHp8QJ!f)|iwhbylnx)Mpq7>vYHe+$ii!#f3=DiE6rFmyd2ai=Ipp!) zTwd`ENQ0xQ2H|vp4ftZR^h*9U8B)s(ugjCpTE-2WoiLC}SK*+pf#)D4BU=HI_|G3t zP-epp>i4T>9=OoHefxF|h_?FKAe;mW;QXG~`zoB%3FP@P!YPqV48~Nsh&l)0ZC5Z{4PmrwN_h6oO&nUUNwS8!>>6EEc*{{(7**_zBicXqy5NfS*Q)bygQrRe>=Ma4ixl(PBrW`rt=7= zMdVwRDyo4Azg(LwRj^{jt0aA+J4VNi;tvgGG6PC&Rpz{@>Z~`VjbA_8OF=89Q(q+{ zy1bt8e1ZJg=Nz&|c0U-mlX2w!8!R0h38{JHsZ))YPBs2q>>+gru@Q&V=d)^xWs3y6 z0`MH{0$@}*n_rRA6BrWKJXRCFp3}UA;y>F?qxL6JfBRo_3CdH?KTF;x<0+tZscq7= z>yeq{_BMmz>?F!z1!;bRkn-g8Z9J>0M!Y7K230GQyug}F8eWq_qwAK__$wbs6APK5uGUIgPonlpLZ0z7gDfxSe1y03>i83@OtmifSZ7aY$je!0%!j4X(_fVO7~Q>hdxQt1qMpS60&G z#u6p87!Yb51_DR4QPff{aIpUr%GGlS`x9oz@T!r`g*5nVI@u)z(NixzD^U77|B_4xV<`|&s?xb+ zNF|RqXW6b_a{nzW=GaUf93`wYI0iGEMAdJU^bHjmIOI&H=9AAy3(5bJ6dH12v8te@ zG^W0Q!W)VN5>%pW)vggZFl@lVmM$98VYRsw(pW&FT8e1MxeOY3bS?!{ve7qYvr^Ke zk@c=iBZty(+ktUAK9gLJMDvPK0KLV4;5jhmca=15_&|lDg%$gaH)kq%5q!zO1)}kT z1oAnZNQ2HMQ^19E3cAF_V08`!*K+o%Uru8i3Mrf$P}D!;8&@ie|BP*2K*GorRrT;I zODX7D9tG4dkygZ)t8R=wysxH{Q+b5#z&LK4NUjwO=Fkk~^(X^6t^m?}N6S{Ij5YO$ z=WsZo7IFi`cNB=8@6TfuEs!wtJC`DNen=JfSvA=->~b!R;2J2HRe~_Wf?|eqbBaB1 zlmXb~gt-e8RV~=YG4aAI+Gb#$pB=zTi6NH*)5+!FbTc3~0i=f4Z&dFQ^~94W12Udb zQ#r$dVvzdXRF86JSO_yCpXYTZk$lc3(V+7wEiHC+ZZ` zO6bktDNu?)sY(_om`mFghT0B})3!)**%w7FuTLYF{ZX9&DgNXB03Z&p(<&eiFC!~S zj9hn~yZBVR;!~#)imWs~*ZVyCR3&G)iz$-je5=w#9lo+1Yzf3vrR-YB&c&59a@=IY zftAyiN#wj|Dmm|(BCi4npjbt&Z|DKd)Mc+Z5=I6!!~h5$WMF7G=RrVobzS^?b7d_f z4(Z7-|KW?r_6^p>B+G?~A}hvWvkk%EPB`zLN~mj`c1$McoeXIA6mr=+)e0chgDlcJ z1A4DRMNkOd7b6EGeT}5{WGDqtCmGHp$n?;F5i6#L=e4y^S?ZA9Sd%RO--a9b31n(W z2)!2|Nt(ySGX%i10Hn4b zmMT&qslzfEo?+AqAk`dB3m`;gXq zNn<+4+_h`oV+M3m7iM}DvEoEYXh*oH#QFAXAJY~sb_pO;0mQNGymK-+l#dsabKE?U zoL;p8NFQQW(!4p$bPcL30Mmh!^{%=!h$<|c_gMF=UD!+H2?y*xUQU)_ILz2#9mClW zp#a*_2@u1BCt1&8Dj-zSdWF2Lhh=4{&8$`v^@yh&JUB~uH7ZX!m}*l*#sK25cDxc= z8zyuBLWphc@E>Qh{~)}kOE{VVp_0}^dP@iEVe90qp7qcWLPIk;1J@h?;IL+#vdUHU zY}ADp40?N{lEL;^QI85pLhP6hk_M{tLZ!_i_FSC*;{k&>M(B8)dbrEuVjU%%B3Lyl zoOP;ttitIOTADfQ0dX%Tko2HbSSTJ{D`Mnxe-Z6xdoTlXMsz$e#aYO!Ax-X*{v5la zP`>LkBwQRfO(aK#Ay5DZkjhm!`moxrhE*px7V7B)$ZXcUoca6hipCIrw%zg&+k=6* zN(R!G*$fEbgY4n7BT`Hd7ljOjng(|fARIJ6@EsVlrX0N?@9Gp**5CjP_h7DENu!9g zUp1Bni|#bnzscjAp;Ot95(P2JXCxpi6pKn$lXTA^ z17DJ+lvB3Mc`)PQ-=*7I0;y;p1*NlU;5F!5u(g5=g0Ny3FjZUxeC0cjP}!_e^O$=s z7&hu1Hf4ma474z(VXu>imbl~ZzCkz36F=Z#FhogO`o7em8Vr%-@emCT%6KWpVg=0i z8lff!NtQCV4`>_s^YHmHPsX!3>XTeD#^f7n-(6!&rE6ZKE_J-XCTyxt6(Ambr_dL9 zA&sNP0hmfPLt!qW!BIP7{P};nQ7HYjQ7M{6_A(iJYO|M1mNyN+x+jdTWtjUPJOqRZ zn^d)2M_7zD*#I#l^17O)Ov*4d0~~qUYM#tV0PugVrP!}z{-W(VV5bw0w^dp~(Zg}s zH@$~++N=&ymNVB)U?K>tXQu@E2rQ*W)vv%zqZafjepW`%zth zfngd-4m6fdTP8gD|4xL}id+iNR54e05Q<7n5c~X?4i7Yomz9>p41c;J?#hEbIR$d-roOxpZA?D zEcTpEMxB>)&up1--rxN1|K9sNuRr;T=kOe!!*h5J&*3>dhv)Ddp2Kr^4$t8^JcsA- z96#p6w0bOs@0d;z@6V&iquKP#=lL|?Xf8#6m`hRn(y7meDfFWN;gvm@%m>n_-}&ch zK+7VEZYia~O=T3*SVlt|%V|X8Vv22AM)A$dX-wNn8rQy>60cR!*w#uKacn+WmXG^k zf%029ih7^Qp?=LJ)W5!%qUwriK<#{ru3JDc7Z%a5i)A$O(qf8lSV{?v6_nUmNfVn^ z)8ytgG^M$UrnXd3(v@mTy0M-nw5_J-?Q_51fV^^|$?|0uMKl*vL|q~EJy%GPPzysD z#895SP)Z{%y+CpGOKDu=N&zvgWi6$(uBTaT8)(kujT|pY%;x(u+I~&b+tyL)jSV#M z@*3*9cIx*JP|&Vq>eF0AeQNXR>2vuMalU~1Gn8j)i$y7b^4z5*G?oD34*xzqXYY-PlfLH+E9_ z&0X|@it?K~sr1GUnty$p00TUzD79rBCAU}8_{*!^A5Pfuc@%yzpP}SXcugLIVYQso z)PfX>VWo^>C=;4iQ5vU4PWu)<;jIE=$;~~q?ABhYxV4WeZtvHE@8h|}H+L&ITSZY& z&P+}>q~7GVDjI*qjp2ly&LYc&Jcg1jYUy30sim({%is$O#blur_(ks3*JvRt1Sh?m z0j#`zfGTglV+08(AYoCVk4rb14u%qy>m52dtJi#JVZSxpJ;tK1Jx$g#O( zW+>*f*<=wgISNd^R-WtT(@?HHs5(d=C9DoBrya%3>)&7bo zCb{KBQQx@66_n7tf=0JixDT9wZIj8;kWXP}v+Thre~DCTfv>=5kp}P!q|OSZ5*^0s zI|n6JNhm-H4pIu$q_Ix zUZfGc1%{i@P{F>kUMdXI0x6Jc*A%j9(%H0=*<%t|ElAPfm&&F5 z$F^5c_~xX}g%kG0JPJFPO<`xU92BEfB%~245x($*rb?Q7`DOXVae_EmN2S~g4gl(^ zL8U?k%jR^Pb#oIQDnZDM`5Qk8BC_Yu?Lec4IR?x zx%$PNMr*_y;1lqS`>Dkqj^;O-YBaAYy|ar7Zofq%U(Y1d)BzMQGnyg~XVH+>avF4j zJL;x#>UVfv=fDX)nL(ipCG=FLf@AM7FkV!nA^ac z;G)|*DgEp^GR619i5t=NiJy{X^As9%X^{(2O}khw0GLcg3x0_aqRsK(52 z9Kk@|Fh=wod0e8)1f&z=HDNoKi~ZuIUcue-J<^e`#Zrw1eV1zoN{{RqKhjOK!hBhOQGE9YH*Zl7>?yE zcfIFwm12q|mGn}b$sU8I4kl_f-+QMJly&PLe-se^`Su(7=G$)x|Ma7-uC7Bc2>;^Y zH0aJ!^3EON8aPj-M@ia*d^VRtK4&;56da`*%NaeD@|4H0`EohMQUag{&0lue)DeuqC@%CMm1l5{Wbaf``;5z(8@7n-jn7UFh11@0wUz-90ey`gTtyp zdYO4N=yg`}7_GTmAmuud8!?Omm~|F$I@xu-cbo&zs($w#{pp{76$sxrK+)5wTeoh` zP`W73>E4x0m1A53CSdy%3OUA5KAmmA2|b=pVP61@1_xkJuKU$$eGC?(M%OPF1J2?( zr=*xDDAfB{_-i{_C!j$K1Vpmr_$xJ61~<>;1>PA9oFypo1wC z{K;$z{&UpU-6ksOC+79x2~6zLI;e}4dqm*AyOYCSABJm zmR{dYzq0tr$qgJ7O}qE(q5ArIYHn_(UAuNsWMt$$Q^+>DJobodzyyCVgMvSr$uY|c zhZPk1xuzQPNlvFz+0^@NF7@SEDe8QYtk?~|SWaUbR!~Z7wG4oOlhyvJs0ZCF)U#ZI zA^r9pDyrW?U7!4!^NDup@=!qZ=pOPb7lC0IL5CU6hYFCuVK7QHW>F3M%o+BXntbYC ztF6Ugy2d0twfRL#X<28$N#{VdD!Kl)^f*W{42z3@zmEnKjsH#%IyB(*i7oj;WOxG5?D1FpejQ>n3QL7V2uV<3o4p_V;jx??GB2_ zi2a|T{4&l$QCCY{mr6nJO}BwF(?}^%&2gxP!LVw=*@Po%w3%s8Z3)HHEu>)=%4EHF zbi;Dl5t!VxM#hDd)^)O014vlDL^GIk?KR4|{RRzqVG?zD^pWobrJLU`=;@=G6xp`G zHDF8!QYh%qbOTQCVVjgXs(Fq1M25iWbsAoiM-gZ9sqfhW>R(exQRj+iAg30FOQ;CV z-xz_kQp|Z$leTR#U3LptNtZX$?5|#>p>JhScb_L73QAY6pHuk3Srpk=LVfFtTvV>N zO(qk-yql`Qd7t5YU`?seV@frgQkIjN*MzefBe1{Jn;-W%!xgJWtp(RMEfS*-=s=X{=P!1%p1PJoyWrYbl# zDRo3Q;&f%in%BUPrJR4E0TT~GssU0>o@}o~vPlnQNQ2e(3d|Y-Rbe`huU|%S%@q`T zrGk3DG?lss{L&c;ChTp~D5`a#fX8QBK6labgI7t6q!3aH!=w`&o0JMW0o7y*2Y@YpUNX{kU;=k1 zkrv4sAgBkab;#axLRDIsk1OSHN=etOmv}%rri~N^Abmy9VGY?f@El$XlgPSv@Z9Fo zWe4w7aTK^GnF4oArNCWDa^JLXniY_4%B-G{kJ*rqvLQn~@D~m|htvzwed!Zx_iVe2 z5vtaBv~?am9somMn6J%||Gw+5Z($e#TPIV%+fyiTI|JG|)eeyEJ$gCE$qOJ=u|hwY zqxC`z(fFH>?FUmsMJKi4G}LB&**Vl}r?oJj&ynxraxlId#*+VAlPKU#4%~7X$K-7X z$S`N^B1Wd+350;OGy{GAk=G_+BXEu<6a))m7qm8y)G=Mb9OpvunKY-6?fZ<#>; zuW`IFu>(L!))cb=WTY58h#>)(nD_zPDwk%o0KxpX`q&}CK<#6Win+!b5z@(b?+uOzaH7}Dz#H9+@M&>?;1N;6IrzyL?g9k=_Z z89fug;eFD1>+#-n8+iOVJhNd*q|>)(dptixp!ohef#5p=39vRNYH8LHpxq8t%x3li zBvA(d9MIA$kpET!koKn-&l^o9-p8K-#rUpIaF4xfUxonb`>c*5-*sd7i*am7P=Is= zDL{q?bx`J&B7)wvfutsQ<96a()H-0ntKdiGpAf-INvMFAFUDH|afcDV6H&-j8^_ppxkncASoV6Y&L&J=)fl15hy5RSoR-v1TNi2b)(jW|F7 z!H|l6Cs2(YV&t5fZVSftnmbK33Jwo%XvNXNnhvJO$zl2yIGi@p^f|%-G%n}<=zG-b zl75_a-Ya7Xt$_t77jwG)|Lpg@ADu$CcKlb6C$d{`c z)C7n~EwueT3WvB4oWPw)ghuY3V2qT?&_;i3xF1v)!({ec+O!q*R8MQpe_K)3OeSs|#RA)!8;hDve!=zNB2!5$CUa~rPNUc2di{!$oSRu!O?${b1x#*45b=X z30*IMV7C)%Em*T*wO|Br8!)n2f9^hu(0HxJ=CN+XNGa?J0M6kV#zq|;JHfAtH5GEpmUP(epmQ3M}xSnoZi zuJcoCzWCgLwHQBPXfG>z~|KYqTp1mT; z`s;H#_*OZm0{qADCOy=)iGG=^v2DUXj-|Qa$ML@&LxK8!kX_io=qQDM&`_j5x{&9* zf%c%CM)oo&@dpbAK7`6pHRCwC$oOx8$Wg5qAoc2-EDM5C)tb#0}AxSDCh@uGMih{C( zEGjArXyh*Cl16D|rY2fiS*Dd6n}X~LDq-79f6O0qnltB2XX?zHrk;7e&-=TVdy&dB zGv|tTcstLzmme45{oLpIKFj;N_3PKS`c~iSTYal<^{u|uxB6D!>RWxQZ}qKveAz4+ zOAZC0WWOei99B&rhwP{6{|>^?w9(|eFP6MNNhSX)xiqRJpMqLfQt;IR3c0$P#$79< z32ntRv287dHW$*k%6tkuoJ20mCt4;fyX{lRt1_K@oAb!8K9>S6=TP9KTzc~IQW{gc zoW|Czpz&8$(ZnljXi|LS6AQyQP4sFr7GTH6MSzPX7eH?O17Z!EG5K(?im$+I?- zyc@E~yC#!HRA-TYO*RGAC@8_T`82L>6@}HWp-6@?t+9k+nl?~e%O;xDvYBSLY|(5p z#kI0s-%8QfH_?-alkZ(XZWSry*|3B>tJBG=DuaBgGs&-J360dCjICWk6RxZl?}%<% zF971NmQv!i?UdBElTzAVFj!LCF1e2H<8^U2wo+8vdU9Ja>D~cky>>i#G-Q!`O*(m0 zrU?{phT>bjgaT@E1WHKlN)DMqn%?v*&1v0Ai>~dUwD#SUb-j#oZ|tR|H}}!9o3DuB zIj&{3mr-i_3j$~^|4dx#CW`6ULV^45f$*~3HI+P?vdFC}mE0>+$+Ie*hBKHE32-^bLa*bR6LC?Pox*Q1*?N z7|w1=(BR_6y+`HPNck%hP>^2Ty*yeuA4#2W{Mb)9e0Gq79A*0Jf~ z0NlzB_L>{}D3e2K@wJ^akHNrWrZts_a7SJ%p`Z`4dJmi-S)<9VNkP$rf!BCcDKH~y zvMBI!9*58>isBRu0fk;*qkytb59QYFhU)172OQnyRC1|GCYK(-KwqFOL6?`w9}d?~IJy&93_yC|z)lXmGkh3YwJL`3j}pDx+D~wy=;FQ3wk< zLKSsUNW&_6vO4eX!qHtxXDEv`OEU2oWF!=Hqd1IE#6cvX4S2`b=)L6^pqPR|NFAc$ z&p52UK0=9SH&WEWJc_C2>KMYymGfxMc=%mXIC6WT+Z=Uw;MgCTr9$XJ&tRZ0zMPHl zhoX>+Wzp4#kI+D6MU`)GI}I5Jn=p3}WjSZ_|!H zo}}W&{q%&NlK?Tc{*OFB-rHx=m}>Pi(32fszDI4}ensE@@IC$GryuB>zy5^|9XLqN z&d#^Nxv&3k$fPuG}NJbLBf6V6==B zTEANAmt+p5Ws;FpnpT;|6bi1FesO}n`RCuLr}f3>pOcl9)opNKcFV?5K+7_LgWny{ zw9LF<5H?Py8O}!uCUD?2t`||@r7#!{rRr=6C8SY^FM1+WuLWGm!YjIJmM$=>S(wlK zxlthe>!%;-$De*8^%|}_f&E^vyhxVSfJpXQE*&7QDERT3XE3uqDSI%ib8Bw z%N7|UHF`#?=h6V`|dmP^785th(UAi?@zjyVkw|` zDS4kyHxC&5H{;0hgLra$f4&JEmya2Y<~42?Q>4JdxB)2?#aHN+H8g{D1|2mTL3GP# z3!pc}T3fLG4{uTW=`GZ+e?N+jj;7B(`^*GNM@I)mMn?X;w;0)gF^=Tlw3K}7vdsg= z;jP)^_}+YF@5htVDFsKo=BxtadLdbwNbf2oz@xRn6h@a(jU_a>vD?R znW}B>zB`7{lj+K0$iE?vd>hRK#__~FayZUlPIQCwq0$;1dyVcq3ov_)S4A4R@pD&( z1vo)kv4<{uR`X_>%N;V{WO8U_GoU<7?mpj7!xP5;S5O|G?JMGoH^sNXOmiAXhT`zn z9CCPjj)L%WFPXUIQ?I;&gg}c#_w}G#OSQbx+m6ps7TrO1!#*lCJIImSHz# z-Ylcc&X>tIE8;(b^03DfGDh{Q&5>ShM7^27pht2zHv4us>^07Mui*^k%21q7Cx}ox z@il-#MT$-sgC$hL7#(1^jchfKy(hl)IaIP5d!KqUiLc%3F$&C44bJhdkV2MnKD|(R%~`H>7?yYwvKGRrDwBdaLxtBD z$@C2%rZqk*$0o>Fu?#DYJqbrAfHl8!2Zg=Aj0TRd`BfzCipVJ~gnskjZ+nLF=mX?h7HiNI)KBo1;r#pD&n1}$%+SJd;wh+S zOyD4-G$Dr9KyTza1Cw;lZG%Tes*DAoGZ5f8En7v5pW;+LzOF!Oov1_i&*`S?8ZfEhH`TY)(^lk5*O9B9r_Q#exi zF(80L785UG0Y*iPx(1c-WKCzFIjD|2 zZHO>7gLfFhJOXD>49Op$s&g1tt_+=fzZV=i*YwP>><< zhL{!1-~@k$5lgoFqRIBv8D#ew1A0BSE4(1i{AdS{;^z=yC)OMke(0ePP6!Q%uy;iU zxwG4Qa-D-(XLv=rm^T-MK9zu#B~`PsCGrS>J^~{{1lW!X=M8{Y&zNQWqT!B0Xm?<3sB%y5@sA;5MVT!IE=#~9KvE8dyQ{J7H2Rn z2swMWpG#K8?>fT46Luk$O+nMc^Wv{@9Wd}({4Bi0h3h7Gi9QqForAXYQ3Ate&s4H` zF^U9~0niMAV#|+!B;mw`9x{__MY4<}Q0$@W9$k}1F8nUzoyO)2_K{}V*RBlDU?#6i zBp3EZ@ecJ+s%OXFrYH!MFMBP=0V6#2q)Ax7m~zlWF(;- z-Flr(kxgN9Qa$%%r+dCG-93PyR6wB#vFESv>bcUOxjy18!=9f^!*)c{u$_@4u=Idf zg8;{nolwtkIAJbqd>{v*bvmgPgD2xaQAJhY|tc-6+z6n-!I6tcb(*AH zsfW;uy*W#M<`)gZ&Ym(jd1UXt<;-gRM1f+pfgd-8Deqx82q{V3$JESNX2dwX)b5f{ z$GcplRi%(4v_h+g><`7MqOk`<8{){}G-$r>y>XM`6Zs($N>&@f4Bi7_Rt4WIm7z|l zj$3~ViNUIH^t(uTn7$u7s8!Vfr9DDlP*C=}*Vdq!-U63^ifLr94S993Q;1FZ9l zOu=Yy;8{`&9Zp1|n_u zs#YZGJ&j>mZwa%k+vgwSVo+)xhJ?@%t-%lr745lhAq6m;WdzI{Ds-$$LM`{h7mp?Q zkU^E=`Fkyau;qoX+tYd#-F{Ji1-A4A$Es1PHPfKn+5D^yfJvK*8;UK*F z$(UnITBcId8Sa7b5gut1N+V?EBI1jw|GQlRjMD;KH{7~bokIBdk41rj zN9c9NwIPEujr!1o>Zn!vhStb^!(s`lq5P!lPIDBA^0UPj^uIQ+X3ubK&Lr2y45?QP zp2VKxj7^`{vXuU_2-*$Qw@vjbRTx^9*Dw&9-I0b(L0sVhI!@*ACNT~qOv{{?yBh3os-$krbXBZ+Kl>h($07*qoM6N<$g79c> AH2?qr literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Run38.png b/examples/moving-saw-platformer/assets/Run38.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5dde820a44874dba7ee57922bb94ef2c7fd581 GIT binary patch literal 4468 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Run42.png b/examples/moving-saw-platformer/assets/Run42.png new file mode 100644 index 0000000000000000000000000000000000000000..5fbff6923f498677562d77c13f6a2426d5a4a40c GIT binary patch literal 4559 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 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Saw_Off.png b/examples/moving-saw-platformer/assets/Saw_Off.png new file mode 100644 index 0000000000000000000000000000000000000000..368b463ea0c6f419698bb2d09d288104cd77a3f2 GIT binary patch literal 451 zcmV;!0X+VRP)2%wDk!JwJfBKb{{so-d=l-r3Cqzch_1E!EZ6X`1=eTr3C;0002ovPDHLkV1hF4v?Txl literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Saw_On_1.png b/examples/moving-saw-platformer/assets/Saw_On_1.png new file mode 100644 index 0000000000000000000000000000000000000000..368b463ea0c6f419698bb2d09d288104cd77a3f2 GIT binary patch literal 451 zcmV;!0X+VRP)2%wDk!JwJfBKb{{so-d=l-r3Cqzch_1E!EZ6X`1=eTr3C;0002ovPDHLkV1hF4v?Txl literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Saw_On_2.png b/examples/moving-saw-platformer/assets/Saw_On_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6c4d4a0faa5a7a8330272d4d1bf6bd9a9fda72f0 GIT binary patch literal 444 zcmV;t0YmjJV1E%k(a6K?LPdH!zB?V?zZ0ZV>1k>Mv6$1mKg5kdm zXp;qoJJnu-r006exA1x|*p;dORe087I{@yK3yIrsCr1IZdu7VZC%0!J4V?hkx8eR^ z?y8L~tn5>h)cFy^aSpyp0*X@0K;Se_`83QIk|DjL6j|80Rdpz3qY&6A mYGp21F>mFBygF3L0`Uv>B>lL|*V+>R0000P) zj20NcSisa}N?WW$FbbComO5o-ogg?cFnH$zMhkcDjzTz^U%AO2J2cD@vT6|BQFLcD z6ID)ws22SNSd~(Q32*VV)^Uh}&2VVee5rDXz?CZ! zdlZ3c^l@C*Nt~2c@&OT&C;R)mq-hF1^Vy=MX#U|KT62Fq+tcOxiDH1#LE1W8i{T0v z3nc-$XH7ax1Jj_2mXIHUx~m4IWnl-?J3*CE4f=Ln}YZ2i{;1ZZ8lolc! znj%kk4JfhP+zx=e3dnZ1|3&~-J1Yo<4M3mWz(@w#j8qz-fe1C`Alg=XtH|;;N@Hp% zZih{K-mJe7v!5Bxx?vyGJC3WR8BR4%%EbC@w6Ddn`3Gz%<6 zXV^q8L!02Z#!{Q92pl)c9P0_nM@ARxZ8%m^p+q=>NHNJ$Zy7;$V#kWdoa9*^ZIJ&A zYc_dAjpgbi1&YH3-ys}EZl_siqiV9yoq-#B!4>*F$u&d!b#=WxJAA%&| z<^l7-7EtE>RvS*`p&lX4Dkt5+s6j0fK!oFt9Saz)O;SlPgTdrDJ1kIfW?A9LjKmPu zRYPXokK=S1w?RA^{S`IuUXq}Sz~zErsMBU0K)ZP@1_P)ZFw$$*NiZ0M6o<747={D! zhSLf~*(5U*#0pnJ7xYy1&AMt!_^6_uJluO7N!>4u|9!i#wq_+n>Q}|KswR{Pu4Mz_ zx-fF-j%$v#Ea2{ko7>b=#&s#KEt*1#fux0-J8?~0CBbQQvN|Pi=u=?Tpd>KKsOs1$ o4W;o!)hAFXL4M}lwbn!M8y4&MP-N(Og#Z8m07*qoM6N<$f(2^8_y7O^ literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Saw_On_6.png b/examples/moving-saw-platformer/assets/Saw_On_6.png new file mode 100644 index 0000000000000000000000000000000000000000..6c143571ada7375302183eb938b20ca90235631b GIT binary patch literal 438 zcmV;n0ZIOeP)a_vF&I4%!#561Y_>Zd?sbuU=nyP~;s&9(uxL|LL0YJ+v4dTb3(6W> zS`YsjSdTMfU{tu#!fJFWMBgx~FiN1IM9R6JmD40JEEF?+3hpDZ`x2=nQC|10{iXk@ z6J}>@>I~F`nd>Nu!RVX|!?z5&Ckuv! z8WbWWt>v3|ZztH4sqa--Yqb>s3zZ`A9%PlCgjiwz`l+9!`xXLn^@Uj zOP)g7E1lavaBT6e79cB$CgL^E=Kk7{+q(GetIZ9RVPK-0qK;oi2Yb3*UN!eE<=Z z6fq{cQ*$T@j3DCZYMgNa;}%K*k^OG>evu0kaf?K7ljHzGd4gr(a%PScEuQ*wEtomC zXd5`NS}3!u#JPdqc|e)r1dVcois3MIlE5thG^dz;QwqId`+;$Wa9;(6a4y?PDle&h zHCPZqWB66dFNrU$%^rjjI8yS*|8BY-#@R|8#4;sT2hEn!1O$R$=W(Nk1E^U(%mo`K z3=qMN>y-&iU8c0fItD|yQn1`Dv*-rFff0}k7#8l*6Gd<#QfMW~pSm>65wdC!o+vz7 z-9(ksAk?C-0Bcf;DB&%hwz>`>*bGNz&6g&ZNUrVo-fGEd)9uz1ic6uI4ysA(mMz?^ zdrGM#tZwVN^puh}+Lk|eie29;QVXH1Xf@IOy&^6-(!)p!&h>@I^7zJqHG#5jKNH=d e``{jrOTnJcvLRXrtS>zP0000xRDDrZ*fD(_J#{rNx0oi=+o=U)4R|TQ40qDIO7}-FZkxCimGg* zGL|02^}Ovb`}I>f*E7ReFE|8s(`mgj!>QrQL)LOZ0^?92U=KKx=dhy=%f*XwexUh2 zEf?%o9TdXl_;zUW6pbN*lPXryOd)VQC~Kl8IX()y+-$?KQVJ!)5kyHyM%`s3)yW+z z9&?gc`E7&zWmvPxBYLdXA0<#6F8K`MP_>;)J0Z)uWnRtq!*;}bwz zAMzYys9Kt-@jF9ZS@pn9J3K2xwPmogTRd(A1j6|pZ}%vxk9OV=Z65a zs0edqc-Kymgx~>!M_lOMpafxMp?ZN9P0~`QCu|ec3Qn%WvxydZ?#{4!0Hwz1>Oy_W z`-5)%{%9{yRuABmmiK0IKyr8!IiOTitbXNj8&p>R)F#K`_quFYjP(q(M#rLZ!`Ld% z`92^#1kY~;7Lh1DOW}~cfL`AQg~<(R^4pvH;o6fm$&z34$JYB696Cr0B-UY2BR01_s7c zo-U3d6}R5bwDn^#F(&eTS(RRse-uMu`c7t zUfYj3_a?9T+c~9Yf2VC<`u1i8jwUp;AZ_maSRY%R-o^6%%P;@?TlDK^U5Tks{j2v& zLJwXzQX`o1#K2OIu|j&i^7SbV8M!~_vk1T2!?NJ*(`PD2ys|SBcn*m+u{dx?CJJm7 z_DVa*!K^U%da~;Cy`LLRI344;*UN5Vj$({3toHacS#f#&^*lF;2IsN{_iy^CwR78b z816bJoV>d|A&0M_+}0q3V~g6MhYVZV9HbZ~8th`&z_oCvRl>`28=h_ES}4G+-qVPd&MM{x45L@8^b6j@Q@JFPt>sYPnOm z(%M<7WqRq}!-Be-Zdux&z1G*1JokNj=DcgWY~5e~iTP}@X8Ckp2k+h4GXxac+c_Ge zm~3{rWY`|dO8pdbyxcfp$>MwYZI_%oYP`2}vPed*3ok-~D@d ze&)%I9UtE@NHE=g{_pktlZNjL85kN^80N*_4=ax75B6hd;9*$u(mmvfg<}NQ1M%b+ Wb5`AYU!?(zY6eeNKbLh*2~7Y{ZRE26 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Trophy_Pressed_2.png b/examples/moving-saw-platformer/assets/Trophy_Pressed_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4d14db670b10c93d8f84e93b6d6f75744feff355 GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GGLLkg|>2BR01_s7c zo-U3d6}R5bwDn^#F(&eTS(RRse-uMu`c7t zUfYj3_a?9T+c~9Yf2VC<`u1i8jwUp;AZ_maSRY%R-o^6%%P;@?TlDK^U5Tks{j2v& zLJwXzQX`o1#K2OIu|j&i^7SbV8M!~_vk1T2!?NJ*(`PD2ys|SBcn*m+u{dx?CJJm7 z_DVa*!K^U%da~;Cy`LLRI344;*UN5Vj$({3toHacS#f#&^*lF;2IsN{_iy^CwR78b z816bJoV>d|A&0M_+}0q3V~g6MhYVZV9HbZ~8th`&z_oCvRl>`28=h_ES}4G+-qVPd&MM{x45L@8^b6j@Q@JFPt>sYPnOm z(%M<7WqRq}!-Be-Zdux&z1G*1JokNj=DcgWY~5e~iTP}@X8Ckp2k+h4GXxac+c_Ge zm~3{rWY`|dO8pdbyxcfp$>MwYZI_%oYP`2}vPed*3ok-~D@d ze&)%I9UtE@NHE=g{_pktlZNjL85kN^80N*_4=ax75B6hd;9*$u(mmvfg<}NQ1M%b+ Wb5`AYU!?(zY6eeNKbLh*2~7Y{ZRE26 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Trophy_Pressed_3.png b/examples/moving-saw-platformer/assets/Trophy_Pressed_3.png new file mode 100644 index 0000000000000000000000000000000000000000..4d14db670b10c93d8f84e93b6d6f75744feff355 GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GGLLkg|>2BR01_s7c zo-U3d6}R5bwDn^#F(&eTS(RRse-uMu`c7t zUfYj3_a?9T+c~9Yf2VC<`u1i8jwUp;AZ_maSRY%R-o^6%%P;@?TlDK^U5Tks{j2v& zLJwXzQX`o1#K2OIu|j&i^7SbV8M!~_vk1T2!?NJ*(`PD2ys|SBcn*m+u{dx?CJJm7 z_DVa*!K^U%da~;Cy`LLRI344;*UN5Vj$({3toHacS#f#&^*lF;2IsN{_iy^CwR78b z816bJoV>d|A&0M_+}0q3V~g6MhYVZV9HbZ~8th`&z_oCvRl>`28=h_ES}4G+-qVPd&MM{x45L@8^b6j@Q@JFPt>sYPnOm z(%M<7WqRq}!-Be-Zdux&z1G*1JokNj=DcgWY~5e~iTP}@X8Ckp2k+h4GXxac+c_Ge zm~3{rWY`|dO8pdbyxcfp$>MwYZI_%oYP`2}vPed*3ok-~D@d ze&)%I9UtE@NHE=g{_pktlZNjL85kN^80N*_4=ax75B6hd;9*$u(mmvfg<}NQ1M%b+ Wb5`AYU!?(zY6eeNKbLh*2~7Y{ZRE26 literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Trophy_Pressed_4.png b/examples/moving-saw-platformer/assets/Trophy_Pressed_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e911ca401aa9a49c0b8e8debc571b0a927f1ec88 GIT binary patch literal 537 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GGLLkg|>2BR01_s8{ zo-U3d6}R5bGW0uYz|(gB+_|nDj6&@V(gqtg7O?j*v?sPt>}{O+)wAbKkE>jd&yyu9 zvzGgP{y*vKFOio^|2?wU`kRlPqe%f3O?&a@P13DHhb;boEU}WkufKf$d-q`FkLgvu zT#SxP8_bF#ntT<_*#o3!>6@$TZF_lbf&4RrCs!9teeU`4mbQ?|K9l5+`D>)sC z?^(%vOcvN;c~;SbVNzY**W&6j&rg#NTzD$SR9?i=kPsxftes5d%_Lf4JJ$s3S12S5(^oZ^sVphx%1wXJ>a*> z3fHF4l#H(pVd68GFN8J9&ev|!ng4&Q)q=F@8IBW{F=hk`ewwq?t8j8%L(2n3Cno-z zTBjQ~Yzo-xaQa+exNm^A#ZJES25&zH?a$wS?)=vC&RchHuc_Zq&0s2fKe33x(#C~P zV=lvPYtEwQ6)XKTL@i?*HAOYERb~1-sM#-TfEXq_%(GuDS2t z$^X-tD)U)_Kk%Or%eM26uiH;fzV;Xxjf@O7`}dg^TgWb-!@wZO;Njh`alWu=gV+Im Y*|KHDKk_WE02MKKy85}Sb4q9e0AZ)%QUCw| literal 0 HcmV?d00001 diff --git a/examples/moving-saw-platformer/assets/Trophy_Pressed_5.png b/examples/moving-saw-platformer/assets/Trophy_Pressed_5.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4d4a55d37d54e4f54744d99744981b9d52f9ce GIT binary patch literal 561 zcmV-10?z%3P)K2xwPmogTRd(A1j6|pZ}%vxk9OV=Z65a zs0edqc-Kymgx~>!M_lOMpafxMp?ZN9P0~`QCu|ec3Qn%WvxydZ?#{4!0Hwz1>Oy_W z`-5)%{%9{yRuABmmiK0IKyr8!IiOTitbXNj8&p>R)F#K`_quFYjP(q(M#rLZ!`Ld% z`92^#1kY~;7Lh1DOW}~cfL`AQg~<(R^4pvH;o6fm$&z34$JYB696Cr0B-UYK2xwPmogTRd(A1j6|pZ}%vxk9OV=Z65a zs0edqc-Kymgx~>!M_lOMpafxMp?ZN9P0~`QCu|ec3Qn%WvxydZ?#{4!0Hwz1>Oy_W z`-5)%{%9{yRuABmmiK0IKyr8!IiOTitbXNj8&p>R)F#K`_quFYjP(q(M#rLZ!`Ld% z`92^#1kY~;7Lh1DOW}~cfL`AQg~<(R^4pvH;o6fm$&z34$JYB696Cr0B-UYb@?P)C=qX)wY7aOdS%&Ux>8z>PzY_mbugiGZ;Hw45y|emv#m z|JGuJ0Vs(8kLsVR`mzpb0IH|Jl-1W@EDnJ8eqdE8Ft!k`4#3zHKm-6l5CCl_=)Dgp z0g&4Xh5(Sx$itAe6Py|u+VyhxrA3Du1a1}p83|sIA4% z*T>tFLO92XFhw5C-BeqQLx=#8u3M!YR+1tTgqKz81x7VVtxiu9P0&ar~nO%HuJZS^cqXuEpoN z_DinTG_lV5U99qy7bKd85c#siA_`?>FQCb0NUfKnnyC#m`OWp+aR2ahG$}q7Fb@?P)C=qX)wY7aOdS%&Ux>8z>PzY_mbugiGZ;Hw45y|emv#m z|JGuJ0Vs(8kLsVR`mzpb0IH|Jl-1W@EDnJ8eqdE8Ft!k`4#3zHKm-6l5CCl_=)Dgp z0g&4Xh5(Sx$itAe6Py|u+VyhxrA3Du1a1}p83|sIA4% z*T>tFLO92XFhw5C-BeqQLx=#8u3M!YR+1tTgqKz81x7VVtxiu9P0&ar~nO%HuJZS^cqXuEpoN z_DinTG_lV5U99qy7bKd85c#siA_`?>FQCb0NUfKnnyC#m`OWp+aR2ahG$}q7F} */", + "const stickerObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const basisObjectsLists = eventsFunctionContext.getObjectsLists(\"BasisObject\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stickerObject, basisObject, stickerBehaviorName) => {", + " const behavior = stickerObject.getBehavior(stickerBehaviorName);", + " return behavior.basisObject === basisObject;", + " },", + " stickerObjectsLists,", + " basisObjectsLists,", + " false,", + " stickerBehaviorName", + ");" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Sticker", + "name": "Object", + "type": "objectList" + }, + { + "description": "Sticker behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + }, + { + "description": "Basis", + "name": "BasisObject", + "type": "objectList" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Stick the object to another. Use the action to stick the object, or unstick it later.", + "fullName": "Sticker", + "name": "Sticker", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "// Set up the scene sticker objects list - if not done already.", + "if (!runtimeScene.__allStickers)", + " runtimeScene.__allStickers = new Set();", + "", + "// Set up the behavior extra methods - if not done already.", + "const prototype = Object.getPrototypeOf(behavior);", + "if (!prototype.updateRelativeCoordinates) {", + " // Unstick from deleted objects.", + " gdjs.registerObjectDeletedFromSceneCallback(function (runtimeScene, deletedObject) {", + " if (!runtimeScene.__allStickers) return;", + "", + " for (const sticker of runtimeScene.__allStickers) {", + " if (sticker.basisObject === deletedObject) {", + " sticker.basisObject = null;", + " }", + " }", + " });", + "", + " /**", + " * Update the coordinates in the basisObject basis.", + " * ", + " * It uses the basisObject coordinates from the previous frame.", + " * This way, the sticker can move relatively to it and still", + " * follow basisObject.", + " * ", + " * @param {gdjs.RuntimeObject} basisObject", + " */", + " prototype.updateRelativeCoordinates = function (basisObject) {", + " const object = this.owner;", + "", + " // Update relative coordinates", + " this.relativeX = object.getX() - this.basisOldX;", + " this.relativeY = object.getY() - this.basisOldY;", + " if (!this._getOnlyFollowPosition()) {", + " this.relativeAngle = object.getAngle() - this.basisOldAngle;", + " this.relativeWidth = object.getWidth() / this.basisOldWidth;", + " this.relativeHeight = object.getHeight() / this.basisOldHeight;", + " const deltaX = object.getCenterXInScene() - this.basisOldCenterXInScene;", + " const deltaY = object.getCenterYInScene() - this.basisOldCenterYInScene;", + " const angle = this.basisOldAngle * Math.PI / 180;", + " this.relativeRotatedX = (deltaX * Math.cos(angle) + deltaY * Math.sin(angle)) / this.basisOldWidth;", + " this.relativeRotatedY = (-deltaX * Math.sin(angle) + deltaY * Math.cos(angle)) / this.basisOldHeight;", + "", + " // Save initial values to avoid calculus and rounding errors", + " this.basisOriginalWidth = basisObject.getWidth();", + " this.basisOriginalHeight = basisObject.getHeight();", + " this.basisOriginalAngle = basisObject.getAngle();", + " }", + " }", + "", + " /**", + " * Copy the coordinates to use it the next frame.", + " * @param basisObject {gdjs.RuntimeObject}", + " */", + " prototype.updateOldCoordinates = function (basisObject) {", + " const object = this.owner;", + "", + " this.ownerOldX = object.getX();", + " this.ownerOldY = object.getY();", + "", + " this.basisOldX = basisObject.getX();", + " this.basisOldY = basisObject.getY();", + "", + " if (!this._getOnlyFollowPosition()) {", + " this.ownerOldAngle = object.getAngle();", + " this.ownerOldWidth = object.getWidth();", + " this.ownerOldHeight = object.getHeight();", + "", + " this.basisOldAngle = basisObject.getAngle();", + " this.basisOldWidth = basisObject.getWidth();", + " this.basisOldHeight = basisObject.getHeight();", + " this.basisOldCenterXInScene = basisObject.getCenterXInScene();", + " this.basisOldCenterYInScene = basisObject.getCenterYInScene();", + " }", + " }", + " /**", + " * Follow the basisObject (called in doStepPostEvents).", + " * ", + " * This method is also called by children to ensure", + " * parents are updated first.", + " */", + " prototype.followBasisObject = function () {", + " if (this.followingDoneThisFrame) {", + " return;", + " }", + " this.followingDoneThisFrame = true;", + " /** @type {gdjs.RuntimeObject} */", + " const basisObject = this.basisObject;", + " if (basisObject) {", + " // If the behavior on the basis object has a different name,", + " // the objects will still follow their basis objects", + " // but frame delays could happen.", + " if (basisObject.hasBehavior(behaviorName)) {", + " const basisBehavior = basisObject.getBehavior(behaviorName);", + " if (basisBehavior.type === this.type) {", + " // Follow parents 1st to avoid frame delays", + " basisBehavior.followBasisObject();", + " }", + " }", + "", + " const object = this.owner;", + "", + " if (this._getOnlyFollowPosition()) {", + " if (object.getX() !== this.ownerOldX", + " || object.getY() !== this.ownerOldY) {", + " this.updateRelativeCoordinates(basisObject);", + " }", + "", + " if (this.basisOldX !== basisObject.getX() ||", + " this.basisOldY !== basisObject.getY()) {", + " object.setPosition(", + " basisObject.getX() + this.relativeX,", + " basisObject.getY() + this.relativeY);", + " }", + " } else {", + " if (object.getX() !== this.ownerOldX", + " || object.getY() !== this.ownerOldY", + " || object.getAngle() !== this.ownerOldAngle", + " || object.getWidth() !== this.ownerOldWidth", + " || object.getHeight() !== this.ownerOldHeight) {", + " this.updateRelativeCoordinates(basisObject);", + " }", + "", + " // Follow basisObject", + " if (basisObject.getAngle() === this.basisOriginalAngle && this.basisOriginalAngle === 0) {", + " if (basisObject.getWidth() === this.basisOriginalWidth ||", + " basisObject.getHeight() === this.basisOriginalHeight) {", + " if (this.basisOldX !== basisObject.getX() ||", + " this.basisOldY !== basisObject.getY()) {", + " object.setPosition(", + " basisObject.getX() + this.relativeX,", + " basisObject.getY() + this.relativeY);", + " }", + " } else {", + " object.setPosition(", + " basisObject.getX() + this.relativeRotatedX * basisObject.getWidth(),", + " basisObject.getY() + this.relativeRotatedY * basisObject.getHeight());", + " }", + " } else {", + " object.setAngle(basisObject.getAngle() + this.relativeAngle);", + "", + " const deltaX = this.relativeRotatedX * basisObject.getWidth();", + " const deltaY = this.relativeRotatedY * basisObject.getHeight();", + " const angle = -basisObject.getAngle() * Math.PI / 180;", + " object.setX(basisObject.getCenterXInScene() + object.getX() - object.getCenterXInScene() + deltaX * Math.cos(angle) + deltaY * Math.sin(angle));", + " object.setY(basisObject.getCenterYInScene() + object.getY() - object.getCenterYInScene() - deltaX * Math.sin(angle) + deltaY * Math.cos(angle));", + " }", + " // Unproportional dimensions changes won't work as expected", + " // if the object angle is not null but nothing more can be done", + " // because there is no full affine transformation on objects.", + " if (basisObject.getWidth() !== this.basisOriginalWidth) {", + " object.setWidth(this.relativeWidth * basisObject.getWidth());", + " }", + " if (basisObject.getHeight() !== this.basisOriginalHeight) {", + " object.setHeight(this.relativeHeight * basisObject.getHeight());", + " }", + " }", + "", + " this.updateOldCoordinates(basisObject);", + " }", + " }", + "}", + "", + "// Register this object as a sticker.", + "runtimeScene.__allStickers.add(behavior);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.followingDoneThisFrame = false;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.followBasisObject();" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Stick on another object.", + "fullName": "Stick", + "functionType": "Action", + "name": "Stick", + "sentence": "Stick _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const basisObjects = eventsFunctionContext.getObjects(\"BasisObject\");", + "", + "if (basisObjects.length === 0) return;", + "const basisObject = basisObjects[0];", + "", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.basisObject = basisObject;", + "behavior.updateOldCoordinates(basisObject);", + "behavior.updateRelativeCoordinates(basisObject);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + }, + { + "description": "Object to stick to", + "name": "BasisObject", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Unstick from the object it was stuck to.", + "fullName": "Unstick", + "functionType": "Action", + "name": "Unstick", + "sentence": "Unstick _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.basisObject = null;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDestroy", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "if (runtimeScene.__allStickers)", + " runtimeScene.__allStickers.delete(behavior);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Boolean", + "label": "Only follow the position", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "OnlyFollowPosition" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "@4ian, Tristan Rhodes (https://victrisgames.itch.io/)", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Ellipse movement", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXNpbmUtd2F2ZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0xNi41LDIxQzEzLjUsMjEgMTIuMzEsMTYuNzYgMTEuMDUsMTIuMjhDMTAuMTQsOS4wNCA5LDUgNy41LDVDNC4xMSw1IDQsMTEuOTMgNCwxMkgyQzIsMTEuNjMgMi4wNiwzIDcuNSwzQzEwLjUsMyAxMS43MSw3LjI1IDEyLjk3LDExLjc0QzEzLjgzLDE0LjggMTUsMTkgMTYuNSwxOUMxOS45NCwxOSAyMC4wMywxMi4wNyAyMC4wMywxMkgyMi4wM0MyMi4wMywxMi4zNyAyMS45NywyMSAxNi41LDIxWiIgLz48L3N2Zz4=", + "name": "EllipseMovement", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/sine-wave.svg", + "shortDescription": "Move objects on ellipses or smoothly back and forth in one direction.", + "version": "1.0.2", + "description": [ + "It allows objects to move:", + "- on an ellipsis or arcs", + "- smoothly vertically or horizontally (by setting one radius to 0)", + "- on a sine wave (by adding a force)", + "", + "It can be used for:", + "- Making objects float, such as powerups or coins", + "- Moving platforms", + "- Enemy movement patterns", + "- Making a player constantly turn right or left ([open the project online](https://editor.gdevelop.io/?project=example://star-seeker))" + ], + "origin": { + "identifier": "EllipseMovement", + "name": "gdevelop-extension-store" + }, + "tags": [ + "sine", + "ellipse", + "movement", + "circular", + "circle", + "floating", + "platform", + "enemy" + ], + "authorIds": [ + "wWP8BSlAW0UP4NeaHa2LcmmDzmH2", + "gqDaZjCfevOOxBYkK6zlhtZnXCg1", + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Move objects on ellipses or smoothly back and forth in one direction.", + "fullName": "Ellipse movement", + "name": "EllipseMovement", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyOldX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyOldY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Evaluate the center of movement from the object position and properties." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyInitialTurningLeft" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "*", + "-1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyMovementAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyInitialDirectionAngle() + 90" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyMovementAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyInitialDirectionAngle() - 90" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X() - Object.Behavior::DeltaX()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y() - Object.Behavior::DeltaY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update the center when the object is moved outside of the behavior." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.X() - Object.Behavior::PropertyOldX()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Y() - Object.Behavior::PropertyOldY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Place the object according to the movement angle." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyRadiusX" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreX" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyCenterX() + Object.Behavior::DeltaX()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyRadiusY" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyCenterY() + Object.Behavior::DeltaY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyShouldRotate" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAngle" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::DirectionAngle() + Object.Behavior::PropertyRotationOffset()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Save the position to detect when the object is moved outside of the behavior." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyOldX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyOldY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update the movement angle for the next frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyMovementAngle" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "360 * TimeDelta() / Object.Behavior::PropertyLoopDuration()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the turning direction (left or right).", + "fullName": "Turn the other way", + "functionType": "Action", + "name": "ToggleTurningLeft", + "sentence": "_PARAM0_ turn the other way", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "2 * Object.X() - Object.Behavior::CenterX()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "2 * Object.Y() - Object.Behavior::CenterY()" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyMovementAngle" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "180" + ] + }, + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "*", + "-1" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the in which side the object is turning (left or right).", + "fullName": "Turn left or right", + "functionType": "Action", + "name": "SetTurningLeft", + "sentence": "_PARAM0_ turn left: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::IsTurningLeft" + }, + "parameters": [ + "Object", + "Behavior", + "yes", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"TurnLeft\"" + ] + } + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "EllipseMovement::EllipseMovement::IsTurningLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"TurnLeft\"" + ] + } + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::ToggleTurningLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + }, + { + "description": "Turn left", + "name": "TurnLeft", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is turning left.", + "fullName": "Is turning left", + "functionType": "Condition", + "name": "IsTurningLeft", + "sentence": "_PARAM0_ is turning left", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the movement angle of the object.", + "fullName": "Movement angle", + "functionType": "Expression", + "name": "MovementAngle", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyMovementAngle()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the loop duration (in seconds).", + "fullName": "Loop duration", + "functionType": "Expression", + "group": "Configuration", + "name": "LoopDuration", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "abs(Object.Behavior::PropertyLoopDuration())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the ellipse radius on X axis.", + "fullName": "Radius X", + "functionType": "Expression", + "group": "Configuration", + "name": "RadiusX", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyRadiusX()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the ellipse radius on X axis.", + "fullName": "Radius Y", + "functionType": "Expression", + "group": "Configuration", + "name": "RadiusY", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyRadiusY()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the movement center position on X axis.", + "fullName": "Movement center X", + "functionType": "Expression", + "group": "Configuration", + "name": "CenterX", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCenterX()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the movement center position on Y axis.", + "fullName": "Movement center Y", + "functionType": "Expression", + "group": "Configuration", + "name": "CenterY", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCenterY()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the radius on X axis of the movement.", + "fullName": "Radius X", + "functionType": "Action", + "group": "Elliptical movement configuration", + "name": "SetRadiusX", + "sentence": "Change the radius on X axis of the movement of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyRadiusX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + }, + { + "description": "Radius X", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the radius on Y axis of the movement.", + "fullName": "Radius Y", + "functionType": "Action", + "group": "Elliptical movement configuration", + "name": "SetRadiusY", + "sentence": "Change the radius on Y axis of the movement of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyRadiusY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + }, + { + "description": "Radius Y", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the loop duration.", + "fullName": "Loop duration", + "functionType": "Action", + "group": "Elliptical movement configuration", + "name": "SetLoopDuration", + "sentence": "Change the loop duration of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::IsTurningLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "-GetArgumentAsNumber(\"Value\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "EllipseMovement::EllipseMovement::IsTurningLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + }, + { + "description": "Speed (in degrees per second)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the movement angle. The object is teleported according to the angle.", + "fullName": "Teleport at an angle", + "functionType": "Action", + "name": "SetMovementAngle", + "sentence": "Teleport _PARAM0_ on the ellipse at _PARAM2_°", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::SetPropertyMovementAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + }, + { + "description": "Movement angle", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "fullName": "Delta X", + "functionType": "Expression", + "name": "DeltaX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "cos(ToRad(Object.Behavior::PropertyMovementAngle())) * Object.Behavior::PropertyRadiusX()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "Delta Y", + "functionType": "Expression", + "name": "DeltaY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "sin(ToRad(Object.Behavior::PropertyMovementAngle())) * Object.Behavior::PropertyRadiusY()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "Direction angle", + "functionType": "Expression", + "name": "DirectionAngle", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyMovementAngle() + 90" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "EllipseMovement::EllipseMovement::PropertyLoopDuration" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyMovementAngle() - 90" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "EllipseMovement::EllipseMovement", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "100", + "type": "Number", + "unit": "Pixel", + "label": "Radius of the movement on X axis", + "description": "", + "group": "Ellipse", + "extraInformation": [], + "hidden": false, + "name": "RadiusX" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Radius of the movement on Y axis", + "description": "", + "group": "Ellipse", + "extraInformation": [], + "hidden": false, + "name": "RadiusY" + }, + { + "value": "6", + "type": "Number", + "unit": "Second", + "label": "Loop duration", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "LoopDuration" + }, + { + "value": "", + "type": "Boolean", + "label": "Turn left", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "InitialTurningLeft" + }, + { + "value": "0", + "type": "Number", + "unit": "DegreeAngle", + "label": "Initial direction", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "InitialDirectionAngle" + }, + { + "value": "", + "type": "Boolean", + "label": "Rotate", + "description": "", + "group": "Rotation", + "extraInformation": [], + "hidden": false, + "name": "ShouldRotate" + }, + { + "value": "0", + "type": "Number", + "unit": "DegreeAngle", + "label": "Rotation offset", + "description": "", + "group": "Rotation", + "extraInformation": [], + "hidden": false, + "name": "RotationOffset" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CenterX" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CenterY" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MovementAngle" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldY" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "Camera", + "extensionNamespace": "", + "fullName": "Smooth Camera", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQoJLnN0MXtmaWxsOm5vbmU7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjI7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEwO30NCjwvc3R5bGU+DQo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjQsMTNoLTZjLTEuMSwwLTItMC45LTItMlY1YzAtMS4xLDAuOS0yLDItMmg2YzEuMSwwLDIsMC45LDIsMnY2QzI2LDEyLjEsMjUuMSwxMywyNCwxM3oiLz4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yNiw4djEwYzAsMS4xLTAuOSwyLTIsMkg4Yy0xLjEsMC0yLTAuOS0yLTJWOGMwLTEuMSwwLjktMiwyLTJoOCIvPg0KPGNpcmNsZSBjbGFzcz0ic3QwIiBjeD0iMjEiIGN5PSI4IiByPSIyIi8+DQo8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIxMSIgY3k9IjE2IiByPSIxIi8+DQo8cmVjdCB4PSI5IiB5PSI5IiBjbGFzcz0ic3QwIiB3aWR0aD0iNCIgaGVpZ2h0PSIzIi8+DQo8cG9seWxpbmUgY2xhc3M9InN0MCIgcG9pbnRzPSIyMSwyOSAyMSwyOSAxMSwyOSAxMSwyOSAiLz4NCjxwb2x5bGluZSBjbGFzcz0ic3QwIiBwb2ludHM9IjE4LDIwIDE4LDI5IDE0LDI5IDE0LDIwICIvPg0KPHJlY3QgeD0iNyIgeT0iMyIgY2xhc3M9InN0MCIgd2lkdGg9IjQiIGhlaWdodD0iMyIvPg0KPC9zdmc+DQo=", + "name": "SmoothCamera", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/Computers and Hardware/Computers and Hardware_camcoder_gopro_go_pro_camera.svg", + "shortDescription": "Smoothly scroll to follow an object.", + "version": "0.3.0", + "description": [ + "The camera follows an object according to:", + "- a frame rate independent catch-up speed to make the scrolling from smooth to strong", + "- a maximum speed to do linear following ([open the project online](https://editor.gdevelop.io/?project=example://platformer-with-tilemap)) or slow down the camera when teleporting the object", + "- a follow-free zone to avoid scrolling on small movements", + "- an offset to see further in one direction", + "- an extra delay and catch-up speed to give an impression of speed (useful for dash)", + "- position forecasting and delay to simulate a cameraman response time", + "", + "A platformer dedicated behavior allows to switch of settings when the character is in air or on the floor. This can be used to stabilize the camera when jumping." + ], + "origin": { + "identifier": "SmoothCamera", + "name": "gdevelop-extension-store" + }, + "tags": [ + "camera", + "scrolling", + "follow", + "smooth" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Smoothly scroll to follow an object.", + "fullName": "Smooth Camera", + "name": "SmoothCamera", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update private properties through setters to check their values and initialize state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetLeftwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyLeftwardSpeed()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetRightwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyRightwardSpeed()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyUpwardSpeed()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyDownwardSpeed()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetLeftwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyLeftwardSpeedMax()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetRightwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyRightwardSpeedMax()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyUpwardSpeedMax()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyDownwardSpeedMax()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaLeft" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyFollowFreeAreaLeft()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaRight" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyFollowFreeAreaRight()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyFollowFreeAreaTop()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaBottom" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyFollowFreeAreaBottom()", + "log(1 - )" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraDelay" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyCameraDelay()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::PropertyIsCalledManually" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::DoMoveCameraCloser" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Move the camera closer to the object. This action must be called after the object has moved for the frame.", + "fullName": "Move the camera closer", + "functionType": "Action", + "name": "MoveCameraCloser", + "sentence": "Move the camera closer to _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The camera following is called with an action, the call from doStepPreEvents must be disabled to avoid to do it twice." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIsCalledManually" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::DoMoveCameraCloser" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Move the camera closer to the object.", + "fullName": "Do move the camera closer", + "functionType": "Action", + "name": "DoMoveCameraCloser", + "private": true, + "sentence": "Do move the camera closer _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Delaying and forecasting can be used at the same time.\nForecasting only use the positions that are older than the one used for delaying.\nThe behavior uses a position history that is split in 2 arrays:\n- one for delaying the position (from TimeFromStart to TimeFromStart - CamearDelay)\n- one for forecasting the position (from TimeFromStart - CamearDelay to TimeFromStart - CamearDelay - ForecastHistoryDuration" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::UpdateDelayedPosition" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::UpdateForecastedPosition" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "At each frame, the camera must catchup the target by a given ratio (speed)\ncameraX(t) - targetX = (cameraX(t - 1) - targetX) * speed\n\nThe frame rate must not impact on the catch-up speed, we don't want a speed in ratio per frame but a speed ratio per second, like this:\ncameraX(t) - targetX = (cameraX(t - 1s) - targetX) * speed\n\nOk, but we still need to process each frame, we can use a exponent for this:\ncameraX(t) - targetX = (cameraX(t - timeDelta) - targetX) * speed^timeDelta\ncameraX(t) = targetX + (cameraX(t - timeDelta) - targetX) * exp(timeDelta * ln(speed))\n\npow is probably more efficient than precalculated log if the speed is changed continuously but this might be rare enough." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowOnX" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyOldX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "CameraX(Object.Layer(), 0)" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraX" + }, + "parameters": [ + "", + ">", + "Object.Behavior::FreeAreaRight()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraX" + }, + "parameters": [ + "", + "=", + "Object.Behavior::FreeAreaRight()\n+ (CameraX(Object.Layer(), 0) - Object.Behavior::FreeAreaRight())\n* exp(TimeDelta() * Object.Behavior::PropertyLogLeftwardSpeed())", + "Object.Layer()", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraX" + }, + "parameters": [ + "", + "<", + "Object.Behavior::PropertyOldX() - Object.Behavior::PropertyLeftwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraX" + }, + "parameters": [ + "", + "=", + "Object.Behavior::PropertyOldX() - Object.Behavior::PropertyLeftwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraX" + }, + "parameters": [ + "", + "<", + "Object.Behavior::FreeAreaLeft()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraX" + }, + "parameters": [ + "", + "=", + "Object.Behavior::FreeAreaLeft()\n+ (CameraX(Object.Layer(), 0) - Object.Behavior::FreeAreaLeft())\n* exp(TimeDelta() * Object.Behavior::PropertyLogRightwardSpeed())", + "Object.Layer()", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraX" + }, + "parameters": [ + "", + ">", + "Object.Behavior::PropertyOldX() + Object.Behavior::PropertyRightwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraX" + }, + "parameters": [ + "", + "=", + "Object.Behavior::PropertyOldX() + Object.Behavior::PropertyRightwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowOnY" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyOldY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "CameraY(Object.Layer(), 0)" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraY" + }, + "parameters": [ + "", + ">", + "Object.Behavior::FreeAreaBottom()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraY" + }, + "parameters": [ + "", + "=", + "Object.Behavior::FreeAreaBottom()\n+ (CameraY(Object.Layer(), 0) - Object.Behavior::FreeAreaBottom())\n* exp(TimeDelta() * Object.Behavior::PropertyLogUpwardSpeed())", + "Object.Layer()", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraY" + }, + "parameters": [ + "", + "<", + "Object.Behavior::PropertyOldY() - Object.Behavior::PropertyUpwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraY" + }, + "parameters": [ + "", + "=", + "Object.Behavior::PropertyOldY() - Object.Behavior::PropertyUpwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraY" + }, + "parameters": [ + "", + "<", + "Object.Behavior::FreeAreaTop()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraY" + }, + "parameters": [ + "", + "=", + "Object.Behavior::FreeAreaTop()\n+ (CameraY(Object.Layer(), 0) - Object.Behavior::FreeAreaTop())\n* exp(TimeDelta() * Object.Behavior::PropertyLogDownwardSpeed())", + "Object.Layer()", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CameraY" + }, + "parameters": [ + "", + ">", + "Object.Behavior::PropertyOldY() + Object.Behavior::PropertyDownwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetCameraY" + }, + "parameters": [ + "", + "=", + "Object.Behavior::PropertyOldY() + Object.Behavior::PropertyDownwardSpeedMax() * TimeDelta()", + "Object.Layer()", + "0" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Delay the camera according to a maximum speed and catch up the delay.", + "fullName": "Wait and catch up", + "functionType": "Action", + "name": "WaitAndCatchUp", + "sentence": "Delay the camera of _PARAM0_ during: _PARAM2_ seconds according to the maximum speed _PARAM3_;_PARAM4_ seconds and catch up in _PARAM5_ seconds", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Maybe the catch-up show be done in constant pixel speed instead of constant time speed." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyWaitingEnd" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "TimeFromStart() + GetArgumentAsNumber(\"WaitingDuration\")" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyWaitingSpeedXMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"WaitingSpeedXMax\")" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyWaitingSpeedYMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"WaitingSpeedYMax\")" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraDelayCatchUpDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"CatchUpDuration\")" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Wait and catch up\"", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Waiting duration (in seconds)", + "name": "WaitingDuration", + "type": "expression" + }, + { + "description": "Waiting maximum camera target speed X", + "name": "WaitingSpeedXMax", + "type": "expression" + }, + { + "description": "Waiting maximum camera target speed Y", + "name": "WaitingSpeedYMax", + "type": "expression" + }, + { + "description": "Catch up duration (in seconds)", + "name": "CatchUpDuration", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Draw the targeted and actual camera position.", + "fullName": "Draw debug", + "functionType": "Action", + "name": "DrawDebug", + "sentence": "Draw targeted and actual camera position for _PARAM0_ on _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "ShapePainter", + "=", + "0" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Path used by the forecasting", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ForecastHistoryTime)", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::OutlineColor" + }, + "parameters": [ + "ShapePainter", + "\"245;166;35\"" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::BeginFillPath" + }, + "parameters": [ + "ShapePainter", + "Object.Variable(__SmoothCamera.ForecastHistoryX[0])", + "Object.Variable(__SmoothCamera.ForecastHistoryY[0])" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "Object.VariableChildCount(__SmoothCamera.ForecastHistoryX)", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::PathLineTo" + }, + "parameters": [ + "ShapePainter", + "Object.Variable(__SmoothCamera.ForecastHistoryX[Object.Behavior::PropertyIndex()])", + "Object.Variable(__SmoothCamera.ForecastHistoryY[Object.Behavior::PropertyIndex()])" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::EndFillPath" + }, + "parameters": [ + "ShapePainter" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Follow-free area.", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowFreeAreaLeft" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowFreeAreaRight" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyFollowFreeAreaBottom" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::OutlineColor" + }, + "parameters": [ + "ShapePainter", + "\"126;211;33\"" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::Rectangle" + }, + "parameters": [ + "ShapePainter", + "Object.Behavior::FreeAreaLeft() - 1", + "Object.Behavior::FreeAreaTop() - 1", + "Object.Behavior::FreeAreaRight() + 1", + "Object.Behavior::FreeAreaBottom() + 1" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Linear regression vector used by the forecasting.", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::OutlineColor" + }, + "parameters": [ + "ShapePainter", + "\"208;2;27\"" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::LineV2" + }, + "parameters": [ + "ShapePainter", + "Object.Behavior::PropertyProjectedOldestX()", + "Object.Behavior::PropertyProjectedOldestY()", + "Object.Behavior::PropertyProjectedNewestX()", + "Object.Behavior::PropertyProjectedNewestY()", + "1" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Targeted and actual camera position", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Circle" + }, + "parameters": [ + "ShapePainter", + "Object.Behavior::PropertyForecastedX()", + "Object.Behavior::PropertyForecastedY()", + "3" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::LineV2" + }, + "parameters": [ + "ShapePainter", + "CameraX(Object.Layer(), 0)", + "CameraY(Object.Layer(), 0) - 4", + "CameraX(Object.Layer(), 0)", + "CameraY(Object.Layer(), 0) + 4", + "1" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::LineV2" + }, + "parameters": [ + "ShapePainter", + "CameraX(Object.Layer(), 0) - 4", + "CameraY(Object.Layer(), 0)", + "CameraX(Object.Layer(), 0) + 4", + "CameraY(Object.Layer(), 0)", + "1" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Shape painter", + "name": "ShapePainter", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Enable or disable the following on X axis.", + "fullName": "Follow on X", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowOnX", + "sentence": "The camera follows _PARAM0_ on X axis: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowOnX" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"FollowOnX\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowOnX" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow on X axis", + "name": "FollowOnX", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Enable or disable the following on Y axis.", + "fullName": "Follow on Y", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowOnY", + "sentence": "The camera follows _PARAM0_ on Y axis: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowOnY" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"FollowOnY\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowOnY" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow on Y axis", + "name": "FollowOnY", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera follow free area right border.", + "fullName": "Follow free area right border", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowFreeAreaRight", + "sentence": "Change the camera follow free area right border of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"SetFollowFreeAreaRight\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow free area right border", + "name": "SetFollowFreeAreaRight", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera follow free area left border.", + "fullName": "Follow free area left border", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowFreeAreaLeft", + "sentence": "Change the camera follow free area left border of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"SetFollowFreeAreaLeft\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow free area left border", + "name": "SetFollowFreeAreaLeft", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera follow free area top border.", + "fullName": "Follow free area top border", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowFreeAreaTop", + "sentence": "Change the camera follow free area top border of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"FollowFreeAreaTop\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow free area top border", + "name": "FollowFreeAreaTop", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera follow free area bottom border.", + "fullName": "Follow free area bottom border", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetFollowFreeAreaBottom", + "sentence": "Change the camera follow free area bottom border of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyFollowFreeAreaBottom" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"SetFollowFreeAreaBottom\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Follow free area bottom border", + "name": "SetFollowFreeAreaBottom", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera leftward maximum speed (in pixels per second).", + "fullName": "Leftward maximum speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetLeftwardSpeedMax", + "sentence": "Change the camera leftward maximum speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLeftwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"Speed\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Leftward maximum speed (in ratio per second)", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera rightward maximum speed (in pixels per second).", + "fullName": "Rightward maximum speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetRightwardSpeedMax", + "sentence": "Change the camera rightward maximum speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLeftwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"Speed\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Rightward maximum speed (in pixels per second)", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera upward maximum speed (in pixels per second).", + "fullName": "Upward maximum speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetUpwardSpeedMax", + "sentence": "Change the camera upward maximum speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyUpwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"Speed\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Upward maximum speed (in pixels per second)", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera downward maximum speed (in pixels per second).", + "fullName": "Downward maximum speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetDownwardSpeedMax", + "sentence": "Change the camera downward maximum speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDownwardSpeedMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, GetArgumentAsNumber(\"Speed\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Downward maximum speed (in pixels per second)", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera leftward catch-up speed (in ratio per second).", + "fullName": "Leftward catch-up speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetLeftwardSpeed", + "sentence": "Change the camera leftward catch-up speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLeftwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "clamp(0, 1, GetArgumentAsNumber(\"LeftwardSpeed\"))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLogLeftwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "log(1 - Object.Behavior::PropertyLeftwardSpeed())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Leftward catch-up speed (in ratio per second)", + "name": "LeftwardSpeed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera rightward catch-up speed (in ratio per second).", + "fullName": "Rightward catch-up speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetRightwardSpeed", + "sentence": "Change the camera rightward catch-up speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyRightwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "clamp(0, 1, GetArgumentAsNumber(\"RightwardSpeed\"))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLogRightwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "log(1 - Object.Behavior::PropertyRightwardSpeed())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Rightward catch-up speed (in ratio per second)", + "name": "RightwardSpeed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera downward catch-up speed (in ratio per second).", + "fullName": "Downward catch-up speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetDownwardSpeed", + "sentence": "Change the camera downward catch-up speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDownwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "clamp(0, 1, GetArgumentAsNumber(\"DownwardSpeed\"))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLogDownwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "log(1 - Object.Behavior::PropertyDownwardSpeed())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Downward catch-up speed (in ratio per second)", + "name": "DownwardSpeed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera upward catch-up speed (in ratio per second).", + "fullName": "Upward catch-up speed", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetUpwardSpeed", + "sentence": "Change the camera upward catch-up speed of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyUpwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "clamp(0, 1, GetArgumentAsNumber(\"UpwardSpeed\"))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyLogUpwardSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "log(1 - Object.Behavior::PropertyUpwardSpeed())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Upward catch-up speed (in ratio per second)", + "name": "UpwardSpeed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the camera offset on X axis of the object. This is not the current difference between the object and the camera position.", + "fullName": "Camera offset X", + "functionType": "ExpressionAndCondition", + "group": "Camera configuration", + "name": "OffsetX", + "sentence": "the camera offset on X axis", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCameraOffsetX()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "OffsetX", + "name": "SetOffsetXOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraOffsetX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera offset on X axis of an object.", + "fullName": "Camera Offset X", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetOffsetX", + "private": true, + "sentence": "Change the camera offset on X axis of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Deprecated use SetOffsetXOp instead." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetOffsetXOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"CameraOffsetX\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Camera offset X", + "name": "CameraOffsetX", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the camera offset on Y axis of the object. This is not the current difference between the object and the camera position.", + "fullName": "Camera offset Y", + "functionType": "ExpressionAndCondition", + "group": "Camera configuration", + "name": "OffsetY", + "sentence": "the camera offset on Y axis", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCameraOffsetY()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "OffsetY", + "name": "SetOffsetYOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Deprecated use SetOffsetYOp instead." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraOffsetY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera offset on Y axis of an object.", + "fullName": "Camera Offset Y", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetOffsetY", + "private": true, + "sentence": "Change the camera offset on Y axis of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetOffsetYOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"CameraOffsetY\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Camera offset Y", + "name": "CameraOffsetY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera forecast time (in seconds).", + "fullName": "Forecast time", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetForecastTime", + "sentence": "Change the camera forecast time of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastTime" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(0, GetArgumentAsNumber(\"ForecastTime\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Forecast time", + "name": "ForecastTime", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the camera delay (in seconds).", + "fullName": "Camera delay", + "functionType": "Action", + "group": "Camera configuration", + "name": "SetCameraDelay", + "sentence": "Change the camera delay of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraDelay" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(0, GetArgumentAsNumber(\"CameraDelay\"))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Camera delay", + "name": "CameraDelay", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return follow free area left border X.", + "fullName": "Free area left", + "functionType": "Expression", + "group": "Private", + "name": "FreeAreaLeft", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyForecastedX() + Object.Behavior::PropertyCameraOffsetX() - Object.Behavior::PropertyFollowFreeAreaLeft()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return follow free area right border X.", + "fullName": "Free area right", + "functionType": "Expression", + "group": "Private", + "name": "FreeAreaRight", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyForecastedX() + Object.Behavior::PropertyCameraOffsetX() + Object.Behavior::PropertyFollowFreeAreaRight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return follow free area bottom border Y.", + "fullName": "Free area bottom", + "functionType": "Expression", + "group": "Private", + "name": "FreeAreaBottom", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyForecastedY() + Object.Behavior::PropertyCameraOffsetY() + Object.Behavior::PropertyFollowFreeAreaBottom()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return follow free area top border Y.", + "fullName": "Free area top", + "functionType": "Expression", + "group": "Private", + "name": "FreeAreaTop", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyForecastedY() + Object.Behavior::PropertyCameraOffsetY() - Object.Behavior::PropertyFollowFreeAreaTop()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Update delayed position and delayed history. This is called in doStepPreEvents.", + "fullName": "Update delayed position", + "functionType": "Action", + "group": "Private", + "name": "UpdateDelayedPosition", + "private": true, + "sentence": "Update delayed position and delayed history of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Add the previous position to have enough (2) positions to evaluate the extra delay for waiting mode." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ObjectTime)", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime", + "TimeFromStart()" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectX", + "Object.Behavior::PropertyDelayedCenterX()" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectY", + "Object.Behavior::PropertyDelayedCenterY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Use the object center when no delay is asked." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.CenterX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.CenterY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::IsDelayed" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::AddForecastHistoryPosition" + }, + "parameters": [ + "Object", + "Behavior", + "TimeFromStart()", + "Object.CenterX()", + "Object.CenterY()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::IsDelayed" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime", + "TimeFromStart()" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectX", + "Object.CenterX()" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectY", + "Object.CenterY()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Remove history entries that are too old to be useful for delaying and pass it to the history for forecasting." + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ObjectTime)", + ">=", + "2" + ] + }, + { + "type": { + "value": "VarObjet" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime[1]", + "<", + "TimeFromStart() - Object.Behavior::CurrentDelay()" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::AddForecastHistoryPosition" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Variable(__SmoothCamera.ObjectTime[0])", + "Object.Variable(__SmoothCamera.ObjectX[0])", + "Object.Variable(__SmoothCamera.ObjectY[0])", + "" + ] + }, + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime", + "0" + ] + }, + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectX", + "0" + ] + }, + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectY", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Don't move the camera if there is not enough history." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Variable(__SmoothCamera.ObjectX[0])" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Variable(__SmoothCamera.ObjectY[0])" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ObjectTime)", + ">=", + "2" + ] + }, + { + "type": { + "value": "VarObjet" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime[0]", + "<", + "TimeFromStart() - Object.Behavior::CurrentDelay()" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Add the extra delay that could be needed to respect the speed limit in waiting mode.\n\nspeedRatio = min(speedMaxX / historySpeedX, speedMaxY / historySpeedY)\ndelay += min(0, timeDelta * (1 - speedRatio))" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraExtraDelay" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "max(0, TimeDelta() * (1 - min(Object.Behavior::PropertyWaitingSpeedXMax() * abs(Object.Variable(__SmoothCamera.ObjectX[1]) - Object.Variable(__SmoothCamera.ObjectX[0])), Object.Behavior::PropertyWaitingSpeedYMax() * abs(Object.Variable(__SmoothCamera.ObjectY[1]) - Object.Variable(__SmoothCamera.ObjectY[0]))) / (Object.Variable(__SmoothCamera.ObjectTime[1]) - Object.Variable(__SmoothCamera.ObjectTime[0]))))" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Extra delay: \" + ToString(Object.Behavior::PropertyCameraExtraDelay())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The time with delay is now between the first 2 indexes" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "lerp(Object.Variable(__SmoothCamera.ObjectX[1]), Object.Variable(__SmoothCamera.ObjectX[0]), ((TimeFromStart() - Object.Behavior::CurrentDelay()) - Object.Variable(__SmoothCamera.ObjectTime[1])) / (Object.Variable(__SmoothCamera.ObjectTime[0]) - Object.Variable(__SmoothCamera.ObjectTime[1])))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyDelayedCenterY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "lerp(Object.Variable(__SmoothCamera.ObjectY[1]), Object.Variable(__SmoothCamera.ObjectY[0]), ((TimeFromStart() - Object.Behavior::CurrentDelay()) - Object.Variable(__SmoothCamera.ObjectTime[1])) / (Object.Variable(__SmoothCamera.ObjectTime[0]) - Object.Variable(__SmoothCamera.ObjectTime[1])))" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::IsDelayed" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectVariableClearChildren" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectTime" + ] + }, + { + "type": { + "value": "ObjectVariableClearChildren" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectX" + ] + }, + { + "type": { + "value": "ObjectVariableClearChildren" + }, + "parameters": [ + "Object", + "__SmoothCamera.ObjectY" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraDelayCatchUpSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyCameraExtraDelay() / Object.Behavior::PropertyCameraDelayCatchUpDuration()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Start to catch up\"", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SmoothCamera::SmoothCamera::IsWaiting" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyCameraExtraDelay" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyCameraExtraDelay" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, Object.Behavior::PropertyCameraExtraDelay() -Object.Behavior::PropertyCameraDelayCatchUpSpeed() * TimeDelta())" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Catching up delay: \" + ToString(Object.Behavior::PropertyCameraExtraDelay())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the camera following target is delayed from the object.", + "fullName": "Camera is delayed", + "functionType": "Condition", + "name": "IsDelayed", + "private": true, + "sentence": "The camera of _PARAM0_ is delayed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::CurrentDelay()", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the current camera delay.", + "fullName": "Current delay", + "functionType": "Expression", + "name": "CurrentDelay", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCameraDelay() + Object.Behavior::PropertyCameraExtraDelay()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the camera following is waiting at a reduced speed.", + "fullName": "Camera is waiting", + "functionType": "Condition", + "name": "IsWaiting", + "private": true, + "sentence": "The camera of _PARAM0_ is waiting", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyWaitingEnd" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "TimeFromStart()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Add a position to the history for forecasting. This is called 2 times in UpadteDelayedPosition.", + "fullName": "Add forecast history position", + "functionType": "Action", + "group": "Private", + "name": "AddForecastHistoryPosition", + "private": true, + "sentence": "Add the time:_PARAM2_ and position: _PARAM3_; _PARAM4_ to the forecast history of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyForecastHistoryDuration" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyForecastTime" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryTime", + "GetArgumentAsNumber(\"Time\")" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryX", + "GetArgumentAsNumber(\"ObjectX\")" + ] + }, + { + "type": { + "value": "ObjectVariablePushNumber" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryY", + "GetArgumentAsNumber(\"ObjectY\")" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Remove history entries that are too old to be useful.\nKeep at least 2 positions because no forecast can be done with less positions." + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ForecastHistoryTime)", + ">=", + "3" + ] + }, + { + "type": { + "value": "VarObjet" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryTime[0]", + "<", + "TimeFromStart() - Object.Behavior::PropertyCameraDelay() - Object.Behavior::PropertyCameraExtraDelay() - Object.Behavior::PropertyForecastHistoryDuration()" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryTime", + "0" + ] + }, + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryX", + "0" + ] + }, + { + "type": { + "value": "ObjectVariableRemoveAt" + }, + "parameters": [ + "Object", + "__SmoothCamera.ForecastHistoryY", + "0" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "Time", + "name": "Time", + "type": "expression" + }, + { + "description": "Object X", + "name": "ObjectX", + "type": "expression" + }, + { + "description": "Object Y", + "name": "ObjectY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Update forecasted position. This is called in doStepPreEvents.", + "fullName": "Update forecasted position", + "functionType": "Action", + "group": "Private", + "name": "UpdateForecastedPosition", + "private": true, + "sentence": "Update forecasted position of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyDelayedCenterX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyDelayedCenterY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Simple linear regression\ny = A * x + B\n\nA = Covariance / VarianceX\nB = MeanY - A * MeanX\n\nNote than we could use only one position every N positions to reduce the process time,\nbut if we really need efficient process JavaScript and circular queues are a must." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.VariableChildCount(__SmoothCamera.ForecastHistoryTime)", + ">=", + "2" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyForecastHistoryDuration" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::PropertyForecastTime" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Mean X", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "Object.VariableChildCount(__SmoothCamera.ForecastHistoryX)", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanX" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Variable(__SmoothCamera.ForecastHistoryX[Object.Behavior::PropertyIndex()])" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanX" + }, + "parameters": [ + "Object", + "Behavior", + "/", + "Object.VariableChildCount(__SmoothCamera.ForecastHistoryX)" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Mean Y", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "Object.VariableChildCount(__SmoothCamera.ForecastHistoryY)", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanY" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Variable(__SmoothCamera.ForecastHistoryY[Object.Behavior::PropertyIndex()])" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryMeanY" + }, + "parameters": [ + "Object", + "Behavior", + "/", + "Object.VariableChildCount(__SmoothCamera.ForecastHistoryY)" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Mean: \" + ToString(Object.Behavior::PropertyForecastHistoryMeanX()) + \" \" + ToString(Object.Behavior::PropertyForecastHistoryMeanY())", + "", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Variance and Covariance", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "VarianceX = sum((X[i] - MeanX)²)\nVarianceY = sum((Y[i] - MeanY)²)\nCovariance = sum((X[i] - MeanX) * (Y[i] - MeanY))" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryVarianceX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryVarianceY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryCovariance" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "Object.VariableChildCount(__SmoothCamera.ForecastHistoryX)", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryVarianceX" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "pow(Object.Variable(__SmoothCamera.ForecastHistoryX[Object.Behavior::PropertyIndex()]) - Object.Behavior::PropertyForecastHistoryMeanX(), 2)" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryVarianceY" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "pow(Object.Variable(__SmoothCamera.ForecastHistoryY[Object.Behavior::PropertyIndex()]) - Object.Behavior::PropertyForecastHistoryMeanY(), 2)" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryCovariance" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "(Object.Variable(__SmoothCamera.ForecastHistoryX[Object.Behavior::PropertyIndex()]) - Object.Behavior::PropertyForecastHistoryMeanX())\n*\n(Object.Variable(__SmoothCamera.ForecastHistoryY[Object.Behavior::PropertyIndex()]) - Object.Behavior::PropertyForecastHistoryMeanY())" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Variances: \" + ToString(Object.Behavior::PropertyForecastHistoryVarianceX()) + \" \" + ToString(Object.Behavior::PropertyForecastHistoryVarianceY()) + \" \" + ToString(Object.Behavior::PropertyForecastHistoryCovariance())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceX())", + "<", + "1" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceY())", + "<", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyDelayedCenterX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyDelayedCenterY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceX())", + ">=", + "1" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceY())", + ">=", + "1" + ] + } + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Linear function parameters", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "y = A * x + B\n\nA = Covariance / VarianceX\nB = MeanY - A * MeanX" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceX())", + ">=", + "abs(Object.Behavior::PropertyForecastHistoryVarianceY())" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryLinearA" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyForecastHistoryCovariance() / Object.Behavior::PropertyForecastHistoryVarianceX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryLinearB" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyForecastHistoryMeanY() - Object.Behavior::PropertyForecastHistoryLinearA() * Object.Behavior::PropertyForecastHistoryMeanX()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Linear: \" + ToString(Object.Behavior::PropertyForecastHistoryLinearA()) + \" \" + ToString(Object.Behavior::PropertyForecastHistoryLinearB())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Projection", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::ProjectHistoryEnds" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Variable(__SmoothCamera.ForecastHistoryX[0])", + "Object.Variable(__SmoothCamera.ForecastHistoryY[0])", + "Object.Variable(__SmoothCamera.ForecastHistoryX[Object.VariableChildCount(__SmoothCamera.ForecastHistoryX) - 1])", + "Object.Variable(__SmoothCamera.ForecastHistoryY[Object.VariableChildCount(__SmoothCamera.ForecastHistoryY) - 1])", + "" + ] + } + ] + } + ], + "parameters": [] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Axis permutation to avoid a ratio between 2 numbers near 0." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyForecastHistoryVarianceX())", + "<", + "abs(Object.Behavior::PropertyForecastHistoryVarianceY())" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryLinearA" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyForecastHistoryCovariance() / Object.Behavior::PropertyForecastHistoryVarianceY()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastHistoryLinearB" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyForecastHistoryMeanX() - Object.Behavior::PropertyForecastHistoryLinearA() * Object.Behavior::PropertyForecastHistoryMeanY()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Linear: \" + ToString(Object.Behavior::PropertyForecastHistoryLinearA()) + \" \" + ToString(Object.Behavior::PropertyForecastHistoryLinearB())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Projection", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::ProjectHistoryEnds" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Variable(__SmoothCamera.ForecastHistoryY[0])", + "Object.Variable(__SmoothCamera.ForecastHistoryX[0])", + "Object.Variable(__SmoothCamera.ForecastHistoryY[Object.VariableChildCount(__SmoothCamera.ForecastHistoryY) - 1])", + "Object.Variable(__SmoothCamera.ForecastHistoryX[Object.VariableChildCount(__SmoothCamera.ForecastHistoryX) - 1])", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Permute back axis" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedOldestX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedOldestX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedOldestY()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedOldestY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyIndex()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedNewestX()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedNewestX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedNewestY()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedNewestY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyIndex()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Oldest: \" + ToString(Object.Behavior::PropertyProjectedOldestX()) + \" \" + ToString(Object.Behavior::PropertyProjectedOldestY())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Newest: \" + ToString(Object.Behavior::PropertyProjectedNewestX()) + \" \" + ToString(Object.Behavior::PropertyProjectedNewestY())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Forecasted position", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedNewestX() + ( Object.Behavior::PropertyProjectedNewestX() - Object.Behavior::PropertyProjectedOldestX()) * Object.Behavior::ForecastTimeRatio()" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyForecastedY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyProjectedNewestY() + ( Object.Behavior::PropertyProjectedNewestY() - Object.Behavior::PropertyProjectedOldestY()) * Object.Behavior::ForecastTimeRatio()" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Forecasted: \" + ToString(Object.Behavior::PropertyForecastedX()) + \" \" + ToString(Object.Behavior::PropertyForecastedY())", + "\"info\"", + "\"SmoothCamera\"" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Project history ends position to have the vector on the line from linear regression. This function is only called by UpdateForecastedPosition.", + "fullName": "Project history ends", + "functionType": "Action", + "group": "Private", + "name": "ProjectHistoryEnds", + "private": true, + "sentence": "Project history oldest: _PARAM2_;_PARAM3_ and newest position: _PARAM4_;_PARAM5_ of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Perpendicular line:\npA = -1/a; \npB = -pA * x + y\n\nIntersection:\n/ ProjectedY = a * ProjectedX + b\n\\ ProjectedY = pA * ProjectedX + b\n\nSolution that is cleaned out from indeterminism (like 0 / 0 or infinity / infinity):\nProjectedX= (x + (y - b) * a) / (a² + 1)\nProjectedY = y + (x * a - y + b) / (a² + 1)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedNewestX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "(GetArgumentAsNumber(\"NewestX\") + (GetArgumentAsNumber(\"NewestY\") - Object.Behavior::PropertyForecastHistoryLinearB()) * Object.Behavior::PropertyForecastHistoryLinearA()) / (1 + pow(Object.Behavior::PropertyForecastHistoryLinearA(), 2))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedNewestY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"NewestY\") + (GetArgumentAsNumber(\"NewestX\") * Object.Behavior::PropertyForecastHistoryLinearA() - GetArgumentAsNumber(\"NewestY\") \n+ Object.Behavior::PropertyForecastHistoryLinearB()) / (1 + pow(Object.Behavior::PropertyForecastHistoryLinearA(), 2))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedOldestX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "(GetArgumentAsNumber(\"OldestX\") + (GetArgumentAsNumber(\"OldestY\") - Object.Behavior::PropertyForecastHistoryLinearB()) * Object.Behavior::PropertyForecastHistoryLinearA()) / (1 + pow(Object.Behavior::PropertyForecastHistoryLinearA(), 2))" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetPropertyProjectedOldestY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"OldestY\") + (GetArgumentAsNumber(\"OldestX\") * Object.Behavior::PropertyForecastHistoryLinearA() - GetArgumentAsNumber(\"OldestY\") \n+ Object.Behavior::PropertyForecastHistoryLinearB()) / (1 + pow(Object.Behavior::PropertyForecastHistoryLinearA(), 2))" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + }, + { + "description": "OldestX", + "name": "OldestX", + "type": "expression" + }, + { + "description": "OldestY", + "name": "OldestY", + "type": "expression" + }, + { + "description": "Newest X", + "name": "NewestX", + "type": "expression" + }, + { + "description": "Newest Y", + "name": "NewestY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the ratio between forecast time and the duration of the history. This function is only called by UpdateForecastedPosition.", + "fullName": "Forecast time ratio", + "functionType": "Expression", + "group": "Private", + "name": "ForecastTimeRatio", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "- Object.Behavior::PropertyForecastTime() / (Object.Variable(__SmoothCamera.ForecastHistoryTime[0]) - Object.Variable(__SmoothCamera.ForecastHistoryTime[Object.VariableChildCount(__SmoothCamera.ForecastHistoryTime) - 1]))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothCamera", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "0.9", + "type": "Number", + "label": "Leftward catch-up speed (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "LeftwardSpeed" + }, + { + "value": "0.9", + "type": "Number", + "label": "Rightward catch-up speed (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "RightwardSpeed" + }, + { + "value": "0.9", + "type": "Number", + "label": "Upward catch-up speed (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "UpwardSpeed" + }, + { + "value": "0.9", + "type": "Number", + "label": "Downward catch-up speed (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "DownwardSpeed" + }, + { + "value": "true", + "type": "Boolean", + "label": "Follow on X axis", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "FollowOnX" + }, + { + "value": "true", + "type": "Boolean", + "label": "Follow on Y axis", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "FollowOnY" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area left border", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FollowFreeAreaLeft" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area right border", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FollowFreeAreaRight" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area top border", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FollowFreeAreaTop" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area bottom border", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FollowFreeAreaBottom" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Camera offset X", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "CameraOffsetX" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Camera offset Y", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "CameraOffsetY" + }, + { + "value": "0", + "type": "Number", + "unit": "Second", + "label": "Camera delay", + "description": "", + "group": "Timing", + "extraInformation": [], + "hidden": false, + "name": "CameraDelay" + }, + { + "value": "0", + "type": "Number", + "unit": "Second", + "label": "Forecast time", + "description": "", + "group": "Timing", + "extraInformation": [], + "hidden": false, + "name": "ForecastTime" + }, + { + "value": "0", + "type": "Number", + "unit": "Second", + "label": "Forecast history duration", + "description": "", + "group": "Timing", + "extraInformation": [], + "hidden": false, + "name": "ForecastHistoryDuration" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LogLeftwardSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LogRightwardSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LogDownwardSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LogUpwardSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DelayedCenterX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DelayedCenterY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryMeanX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryMeanY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryVarianceX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryCovariance" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryLinearA" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryLinearB" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastedX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastedY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ProjectedNewestX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ProjectedNewestY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ProjectedOldestX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ProjectedOldestY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ForecastHistoryVarianceY" + }, + { + "value": "", + "type": "Number", + "label": "Index (local variable)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Index" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CameraDelayCatchUpSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CameraExtraDelay" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "WaitingSpeedXMax" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "WaitingSpeedYMax" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "WaitingEnd" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CameraDelayCatchUpDuration" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Leftward maximum speed", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "LeftwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Rightward maximum speed", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "RightwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Upward maximum speed", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "UpwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Downward maximum speed", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "DownwardSpeedMax" + }, + { + "value": "", + "type": "Number", + "label": "OldX (local variable)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldX" + }, + { + "value": "", + "type": "Number", + "label": "OldY (local variable)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldY" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsCalledManually" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Smoothly scroll to follow a character and stabilize the camera when jumping.", + "fullName": "Smooth platformer camera", + "name": "SmoothPlatformerCamera", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::IsJumping" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + }, + { + "type": { + "inverted": true, + "value": "PlatformBehavior::IsFalling" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaBottom" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorFollowFreeAreaTop()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorFollowFreeAreaBottom()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeed" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorUpwardSpeed()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeed" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorDownwardSpeed()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeedMax" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorUpwardSpeedMax()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeedMax" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyFloorDownwardSpeedMax()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "PlatformBehavior::IsJumping" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + }, + { + "type": { + "value": "PlatformBehavior::IsFalling" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaBottom" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirFollowFreeAreaTop()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetFollowFreeAreaTop" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirFollowFreeAreaBottom()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeed" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirUpwardSpeed()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeed" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirDownwardSpeed()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetUpwardSpeedMax" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirUpwardSpeedMax()", + "" + ] + }, + { + "type": { + "value": "SmoothCamera::SmoothCamera::SetDownwardSpeedMax" + }, + "parameters": [ + "Object", + "SmoothCamera", + "Object.Behavior::PropertyAirDownwardSpeedMax()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "SmoothCamera::SmoothPlatformerCamera", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Platformer character behavior", + "description": "", + "group": "", + "extraInformation": [ + "PlatformBehavior::PlatformerObjectBehavior" + ], + "hidden": false, + "name": "PlatformerCharacter" + }, + { + "value": "", + "type": "Behavior", + "label": "Smooth camera behavior", + "description": "", + "group": "", + "extraInformation": [ + "SmoothCamera::SmoothCamera" + ], + "hidden": false, + "name": "SmoothCamera" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "JumpOriginY" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area top in the air", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "AirFollowFreeAreaTop" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area bottom in the air", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "AirFollowFreeAreaBottom" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area top on the floor", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FloorFollowFreeAreaTop" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Follow free area bottom on the floor", + "description": "", + "group": "Position", + "extraInformation": [], + "hidden": false, + "name": "FloorFollowFreeAreaBottom" + }, + { + "value": "0.95", + "type": "Number", + "label": "Upward speed in the air (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "AirUpwardSpeed" + }, + { + "value": "0.95", + "type": "Number", + "label": "Downward speed in the air (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "AirDownwardSpeed" + }, + { + "value": "0.9", + "type": "Number", + "label": "Upward speed on the floor (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "FloorUpwardSpeed" + }, + { + "value": "0.9", + "type": "Number", + "label": "Downward speed on the floor (in ratio per second)", + "description": "", + "group": "Catch-up speed", + "extraInformation": [], + "hidden": false, + "name": "FloorDownwardSpeed" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Upward maximum speed in the air", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "AirUpwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Downward maximum speed in the air", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "AirDownwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Upward maximum speed on the floor", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "FloorUpwardSpeedMax" + }, + { + "value": "9000", + "type": "Number", + "unit": "PixelSpeed", + "label": "Downward maximum speed on the floor", + "description": "", + "group": "Maximum speed", + "extraInformation": [], + "hidden": false, + "name": "FloorDownwardSpeedMax" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "Bouh", + "category": "Input", + "extensionNamespace": "", + "fullName": "Gamepads (controllers)", + "helpPath": "/all-features/gamepad", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWdhbWVwYWQtdmFyaWFudC1vdXRsaW5lIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTYsOUg4VjExSDEwVjEzSDhWMTVINlYxM0g0VjExSDZWOU0xOC41LDlBMS41LDEuNSAwIDAsMSAyMCwxMC41QTEuNSwxLjUgMCAwLDEgMTguNSwxMkExLjUsMS41IDAgMCwxIDE3LDEwLjVBMS41LDEuNSAwIDAsMSAxOC41LDlNMTUuNSwxMkExLjUsMS41IDAgMCwxIDE3LDEzLjVBMS41LDEuNSAwIDAsMSAxNS41LDE1QTEuNSwxLjUgMCAwLDEgMTQsMTMuNUExLjUsMS41IDAgMCwxIDE1LjUsMTJNMTcsNUE3LDcgMCAwLDEgMjQsMTJBNyw3IDAgMCwxIDE3LDE5QzE1LjA0LDE5IDEzLjI3LDE4LjIgMTIsMTYuOUMxMC43MywxOC4yIDguOTYsMTkgNywxOUE3LDcgMCAwLDEgMCwxMkE3LDcgMCAwLDEgNyw1SDE3TTcsN0E1LDUgMCAwLDAgMiwxMkE1LDUgMCAwLDAgNywxN0M4LjY0LDE3IDEwLjA5LDE2LjIxIDExLDE1SDEzQzEzLjkxLDE2LjIxIDE1LjM2LDE3IDE3LDE3QTUsNSAwIDAsMCAyMiwxMkE1LDUgMCAwLDAgMTcsN0g3WiIgLz48L3N2Zz4=", + "name": "Gamepads", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/gamepad-variant-outline.svg", + "shortDescription": "Add support for gamepads (or other controllers) to your game, giving access to information such as button presses, axis positions, trigger pressure, etc...", + "version": "0.6.1", + "description": [ + "Add support for gamepads (or other controllers).", + "", + "It gives access to:", + "- button presses", + "- axis positions and force", + "- trigger pressure", + "- configurable deadzone", + "- vibration", + "- automatic mappers for platformer characters and top-down movement", + "", + "The Bomberman-like example handles 4 players with gamepads ([open the project online](https://editor.gdevelop.io/?project=example://goose-bomberman))." + ], + "origin": { + "identifier": "Gamepads", + "name": "gdevelop-extension-store" + }, + "tags": [ + "controllers", + "gamepads", + "joysticks", + "axis", + "xbox", + "ps4" + ], + "authorIds": [ + "2OwwM8ToR9dx9RJ2sAKTcrLmCB92", + "taRwmWxwAFYFL9yyBwB3cwBw0BO2", + "mnImQKdn8nQxwzkS5D6a1JB27V23" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Get the value of the pressure on a gamepad trigger.", + "fullName": "Pressure on a gamepad trigger", + "functionType": "Expression", + "name": "TriggerPressure", + "sentence": "Player _PARAM1_ push axis _PARAM2_ to _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const trigger = eventsFunctionContext.getArgument(\"trigger\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in expression: \"Pressure on a gamepad trigger\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "if (trigger != \"LT\" && trigger != \"RT\" && trigger != \"L2\" && trigger != \"R2\") {\r", + " console.error('Parameter trigger is not valid in expression: \"Pressure on a gamepad trigger\"');\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "switch (trigger) {\r", + " case 'LT':\r", + " case 'L2':\r", + " eventsFunctionContext.returnValue = gamepad.buttons[6].value;\r", + " break;\r", + "\r", + " case 'RT':\r", + " case 'R2':\r", + " eventsFunctionContext.returnValue = gamepad.buttons[7].value;\r", + " break;\r", + "\r", + " default:\r", + " eventsFunctionContext.returnValue = -1;\r", + " break;\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Trigger button", + "name": "trigger", + "supplementaryInformation": "[\"LT\",\"RT\",\"L2\",\"R2\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "the force of gamepad stick (from 0 to 1).", + "fullName": "Stick force", + "functionType": "ExpressionAndCondition", + "name": "StickForce", + "sentence": "the gamepad _PARAM1_ _PARAM2_ stick force", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"stick\").toUpperCase();\r", + "\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier is not valid in expression: \"Value of a stick force\"');\r", + " return;\r", + "}\r", + "\r", + "if (stick !== \"LEFT\" && stick !== \"RIGHT\") {\r", + " console.error('Parameter stick is not valid in expression: \"Value of a stick force\"');\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "\r", + "switch (stick) {\r", + " case 'LEFT':\r", + " eventsFunctionContext.returnValue = gdjs.evtTools.common.clamp(Math.abs(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId)) + Math.abs(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId)), 0, 1);\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " eventsFunctionContext.returnValue = gdjs.evtTools.common.clamp(Math.abs(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId)) + Math.abs(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId)), 0, 1);\r", + " break;\r", + "\r", + " default:\r", + " eventsFunctionContext.returnValue = -1;\r", + " break;\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Get the rotation value of a gamepad stick.\nIf the deadzone value is high, the angle value is rounded to main axes, left, left, up, down.\nAn zero deadzone value give a total freedom on the angle value.", + "fullName": "Value of a stick rotation (deprecated)", + "functionType": "Expression", + "name": "StickRotationValue", + "private": true, + "sentence": "Player _PARAM1_ push axis _PARAM2_ to _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Gamepads::StickAngle(GetArgumentAsNumber(\"player_ID\"), GetArgumentAsString(\"stick\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the angle of a gamepad stick.\nIf the deadzone value is high, the angle value is rounded to main axes, left, left, up, down.\nAn zero deadzone value give a total freedom on the angle value.", + "fullName": "Stick angle", + "functionType": "Expression", + "name": "StickAngle", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"stick\").toUpperCase();\r", + "\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier is not valid in expression: \"Value of a stick rotation\"');\r", + " return;\r", + "}\r", + "if (stick !== \"LEFT\" && stick !== \"RIGHT\") {\r", + " console.error('Parameter stick is not valid in expression: \"Value of a stick rotation\"');\r", + " return;\r", + "}\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "switch (stick) {\r", + " case 'LEFT':\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.axisToAngle(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId), gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId));\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.axisToAngle(gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId), gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId));\r", + " break;\r", + "\r", + " default:\r", + " eventsFunctionContext.returnValue = -1;\r", + " break;\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Get the value of axis of a gamepad stick.", + "fullName": "Value of a gamepad axis (deprecated)", + "functionType": "Expression", + "name": "AxisValue", + "private": true, + "sentence": "Player _PARAM1_ push axis _PARAM2_ to _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"stick\").toUpperCase();\r", + "const direction = eventsFunctionContext.getArgument(\"direction\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "if (stick != \"LEFT\" && stick != \"RIGHT\") {\r", + " console.error('Parameter stick is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "if (direction != \"UP\" && direction != \"DOWN\" && direction != \"LEFT\" && direction != \"RIGHT\" && direction != \"HORIZONTAL\" && direction != \"VERTICAL\") {\r", + " console.error('Parameter direction is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "let parameterError = false;\r", + "switch (stick) {\r", + " case 'LEFT':\r", + " switch (direction) {\r", + " case 'LEFT':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = -gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'UP':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = -gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'DOWN':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId);\r", + " }\r", + " break;\r", + "\r", + " case \"HORIZONTAL\":\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[0], playerId);\r", + " break;\r", + "\r", + " case \"VERTICAL\":\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[1], playerId);\r", + " break;\r", + "\r", + " default:\r", + " break;\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " switch (direction) {\r", + " case 'LEFT':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = -gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'UP':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = -gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId);\r", + " }\r", + " break;\r", + "\r", + " case 'DOWN':\r", + " if (gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId);\r", + " }\r", + " break;\r", + "\r", + " case \"HORIZONTAL\":\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[2], playerId);\r", + " break;\r", + "\r", + " case \"VERTICAL\":\r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[3], playerId);\r", + " break;\r", + "\r", + " default:\r", + " break;\r", + " }\r", + " break;\r", + "\r", + " default:\r", + " break;\r", + "}\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + }, + { + "description": "Direction", + "name": "direction", + "supplementaryInformation": "[\"Up\",\"Down\",\"Left\",\"Right\",\"Horizontal\",\"Vertical\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the gamepad stick force on X axis (from -1 at the left to 1 at the right).", + "fullName": "Stick X force", + "functionType": "Expression", + "name": "StickForceX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"Gamepad\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"Stick\").toLowerCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "if (stick != \"left\" && stick != \"right\") {\r", + " console.error('Parameter stick is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "const axisIndex = stick === 'right' ? 2 : 0;\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[axisIndex], playerId);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Gamepad", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "Stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the gamepad stick force on Y axis (from -1 at the top to 1 at the bottom).", + "fullName": "Stick Y force", + "functionType": "Expression", + "name": "StickForceY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"Gamepad\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"Stick\").toLowerCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "if (stick != \"left\" && stick != \"right\") {\r", + " console.error('Parameter stick is not valid in expression: \"Value of a gamepad axis\"');\r", + " return;\r", + "}\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "const axisIndex = stick === 'right' ? 3 : 1;\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.getNormalizedAxisValue(gamepad.axes[axisIndex], playerId);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Gamepad", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "Stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Test if a button is released on a gamepad. Buttons can be:\n* Xbox: \"A\", \"B\", \"X\", \"Y\", \"LB\", \"RB\", \"LT\", \"RT\", \"BACK\", \"START\",\n* PS4: \"CROSS\", \"SQUARE\", \"CIRCLE\", \"TRIANGLE\", \"L1\", \"L2\", \"R1\", \"R2\", \"SHARE\", \"OPTIONS\", \"PS_BUTTON\", \"CLICK_TOUCHPAD\",\n* Other: \"UP\", \"DOWN\", \"LEFT\", \"RIGHT\", \"CLICK_STICK_LEFT\", \"CLICK_STICK_RIGHT\".", + "fullName": "Gamepad button released", + "functionType": "Condition", + "name": "C_Button_released", + "sentence": "Button _PARAM2_ of gamepad _PARAM1_ is released", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const button = eventsFunctionContext.getArgument(\"button\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in condition: \"Gamepad button released\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "if (button === \"\") {\r", + " console.error('Parameter button is not valid in condition: \"Gamepad button released\"');\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "let buttonId;\r", + "\r", + "switch (button) {\r", + " case 'A':\r", + " case 'CROSS':\r", + " buttonId = 0;\r", + " break;\r", + " case 'B':\r", + " case 'CIRCLE':\r", + " buttonId = 1;\r", + " break;\r", + " case 'X':\r", + " case 'SQUARE':\r", + " buttonId = 2;\r", + " break;\r", + " case 'Y':\r", + " case 'TRIANGLE':\r", + " buttonId = 3;\r", + " break;\r", + " case 'LB':\r", + " case 'L1':\r", + " buttonId = 4;\r", + " break;\r", + " case 'RB':\r", + " case 'R1':\r", + " buttonId = 5;\r", + " break;\r", + " case 'LT':\r", + " case 'L2':\r", + " buttonId = 6;\r", + " break;\r", + " case 'RT':\r", + " case 'R2':\r", + " buttonId = 7;\r", + " break;\r", + "\r", + " case 'UP':\r", + " buttonId = 12;\r", + " break;\r", + " case 'DOWN':\r", + " buttonId = 13;\r", + " break;\r", + " case 'LEFT':\r", + " buttonId = 14;\r", + " break;\r", + " case 'RIGHT':\r", + " buttonId = 15;\r", + " break;\r", + "\r", + " case 'BACK':\r", + " case 'SHARE':\r", + " buttonId = 8;\r", + " break;\r", + " case 'START':\r", + " case 'OPTIONS':\r", + " buttonId = 9;\r", + " break;\r", + "\r", + " case 'CLICK_STICK_LEFT':\r", + " buttonId = 10;\r", + " break;\r", + " case 'CLICK_STICK_RIGHT':\r", + " buttonId = 11;\r", + " break;\r", + "\r", + " //PS4\r", + " case 'PS_BUTTON':\r", + " buttonId = 16;\r", + " break;\r", + " case 'CLICK_TOUCHPAD':\r", + " buttonId = 17;\r", + " break;\r", + "\r", + " default:\r", + " console.error('The button: ' + button + ' in condition: \"Gamepad button released\" is not valid.');\r", + " break;\r", + "}\r", + "\r", + "if (buttonId === undefined) {\r", + " console.error('There is no buttons valid in condition: \"Gamepad button released\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "if (gamepad.buttons == null || gamepad.buttons[buttonId] == null) {\r", + " console.error('Buttons on the gamepad are not accessible in condition: \"Gamepad button released\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "//Define default value on pressed button or use previous value\r", + "gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId] = gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId] || { pressed: false };\r", + "\r", + "//Get state of button at previous frame\r", + "const previousStateButton = gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed;\r", + "\r", + "//When previousStateButton is true and actual button state is not pressed\r", + "//Player have release the button\r", + "if (previousStateButton === true && gamepad.buttons[buttonId].pressed === false) {\r", + " // Save the last button used for the player \r", + " gdjs._extensionController.players[playerId].lastButtonUsed = buttonId;\r", + " gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed = true;\r", + " eventsFunctionContext.returnValue = true;\r", + "\r", + "} else {\r", + " gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed = false;\r", + " eventsFunctionContext.returnValue = false;\r", + "}\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Name of the button", + "name": "button", + "supplementaryInformation": "[\"A\",\"Cross\",\"B\",\"Circle\",\"X\",\"Square\",\"Y\",\"Triangle\",\"LB\",\"L1\",\"RB\",\"R1\",\"LT\",\"L2\",\"RT\",\"R2\",\"Up\",\"Down\",\"Left\",\"Right\",\"Back\",\"Share\",\"Start\",\"Options\",\"Click_Stick_Left\",\"Click_Stick_Right\",\"PS_Button\",\"Click_Touchpad\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the index of the last pressed button of a gamepad.", + "fullName": "Last pressed button (id)", + "functionType": "Expression", + "name": "LastButtonID", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//Get function parameter\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "\r", + "//Player id is not valid\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in expression: \"Last pressed button (id)\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "\r", + "//Return the last button used by the player\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.players[playerId].lastButtonUsed;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if any button is pressed on a gamepad.", + "fullName": "Any gamepad button pressed", + "functionType": "Condition", + "name": "C_Any_Button_pressed", + "sentence": "Any button of gamepad _PARAM1_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameter\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in condition: \"Any gamepad button pressed\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "let buttonId;\r", + "for (let i = 0; i < gamepad.buttons.length; i++) { //For each buttons\r", + " if (gamepad.buttons[i].pressed) { //One of them is pressed\r", + " buttonId = i; //Save the button pressed\r", + " break;\r", + " }\r", + "}\r", + "\r", + "if (buttonId === undefined) {\r", + " // No buttons are pressed.\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "if (gamepad.buttons == null || gamepad.buttons[buttonId] == null) {\r", + " console.error('Buttons on the gamepad are not accessible in condition: \"Any gamepad button pressed\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "//When a button is pressed, save the button in lastButtonUsed for each players\r", + "if (gamepad.buttons[buttonId].pressed) gdjs._extensionController.players[playerId].lastButtonUsed = buttonId;\r", + "eventsFunctionContext.returnValue = gamepad.buttons[buttonId].pressed;\r", + "\r", + "\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the last button pressed. \nButtons for Xbox and PS4 can be:\n* Xbox: \"A\", \"B\", \"X\", \"Y\", \"LB\", \"RB\", \"LT\", \"RT\", \"BACK\", \"START\",\n* PS4: \"CROSS\", \"SQUARE\", \"CIRCLE\", \"TRIANGLE\", \"L1\", \"L2\", \"R1\", \"R2\", \"SHARE\", \"OPTIONS\", \"PS_BUTTON\", \"CLICK_TOUCHPAD\",\n* Both: \"UP\", \"DOWN\", \"LEFT\", \"RIGHT\", \"CLICK_STICK_LEFT\", \"CLICK_STICK_RIGHT\".", + "fullName": "Last pressed button (string)", + "functionType": "StringExpression", + "name": "LastButtonString", + "sentence": "Button _PARAM2_ of gamepad _PARAM1_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const controllerType = eventsFunctionContext.getArgument(\"controller_type\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in string expression: \"Last pressed button (LastButtonString)\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "if (controllerType === \"\") {\r", + " console.error('Parameter controller type is not valid in string expression: \"Last pressed button (LastButtonString)\"');\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "if (gamepad !== null) { //Gamepad exist\r", + " //Get last btn id\r", + " const lastButtonUsedID = gdjs._extensionController.players[playerId].lastButtonUsed;\r", + "\r", + " //Return last button as string \r", + " eventsFunctionContext.returnValue = gdjs._extensionController.getInputString(controllerType, lastButtonUsedID);\r", + "\r", + "} else { //Gamepad dosen't exist\r", + " console.error('Your controller is not supported or the gamepad wasn\\'t detected in string expression: \"Last pressed button (LastButtonString)\"');\r", + " eventsFunctionContext.returnValue = \"Gamepad not connected\";\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Controller type", + "name": "controller_type", + "supplementaryInformation": "[\"Xbox\",\"PS4\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of gamepads.", + "fullName": "Gamepad count", + "functionType": "Expression", + "name": "GamepadCount", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get the last activated controller\r", + "const controllerId = gdjs._extensionController.lastActiveController;\r", + "\r", + "// Check if controller is active\r", + "const gamepad = gamepads[controllerId];\r", + "if (gamepad == null) {\r", + " eventsFunctionContext.returnValue = 0;\r", + "} else {\r", + " // Return active controller id\r", + " eventsFunctionContext.returnValue = controllerId + 1;\r", + "}\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Check if a button is pressed on a gamepad. \nButtons can be:\n* Xbox: \"A\", \"B\", \"X\", \"Y\", \"LB\", \"RB\", \"LT\", \"RT\", \"BACK\", \"START\",\n* PS4: \"CROSS\", \"SQUARE\", \"CIRCLE\", \"TRIANGLE\", \"L1\", \"L2\", \"R1\", \"R2\", \"SHARE\", \"OPTIONS\", \"PS_BUTTON\", \"CLICK_TOUCHPAD\",\n* Other: \"UP\", \"DOWN\", \"LEFT\", \"RIGHT\", \"CLICK_STICK_LEFT\", \"CLICK_STICK_RIGHT\".", + "fullName": "Gamepad button pressed", + "functionType": "Condition", + "name": "C_Button_pressed", + "sentence": "Button _PARAM2_ of gamepad _PARAM1_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const button = eventsFunctionContext.getArgument(\"button\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in condition: \"Gamepad button pressed\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "if (button === \"\") {\r", + " console.error('Parameter button is not valid in condition: \"Gamepad button pressed\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "let buttonId;\r", + "\r", + "switch (button) {\r", + " case 'A':\r", + " case 'CROSS':\r", + " buttonId = 0;\r", + " break;\r", + " case 'B':\r", + " case 'CIRCLE':\r", + " buttonId = 1;\r", + " break;\r", + " case 'X':\r", + " case 'SQUARE':\r", + " buttonId = 2;\r", + " break;\r", + " case 'Y':\r", + " case 'TRIANGLE':\r", + " buttonId = 3;\r", + " break;\r", + " case 'LB':\r", + " case 'L1':\r", + " buttonId = 4;\r", + " break;\r", + " case 'RB':\r", + " case 'R1':\r", + " buttonId = 5;\r", + " break;\r", + " case 'LT':\r", + " case 'L2':\r", + " buttonId = 6;\r", + " break;\r", + " case 'RT':\r", + " case 'R2':\r", + " buttonId = 7;\r", + " break;\r", + "\r", + " case 'UP':\r", + " buttonId = 12;\r", + " break;\r", + " case 'DOWN':\r", + " buttonId = 13;\r", + " break;\r", + " case 'LEFT':\r", + " buttonId = 14;\r", + " break;\r", + " case 'RIGHT':\r", + " buttonId = 15;\r", + " break;\r", + "\r", + " case 'BACK':\r", + " case 'SHARE':\r", + " buttonId = 8;\r", + " break;\r", + " case 'START':\r", + " case 'OPTIONS':\r", + " buttonId = 9;\r", + " break;\r", + "\r", + " case 'CLICK_STICK_LEFT':\r", + " buttonId = 10;\r", + " break;\r", + " case 'CLICK_STICK_RIGHT':\r", + " buttonId = 11;\r", + " break;\r", + "\r", + " //PS4\r", + " case 'PS_BUTTON':\r", + " buttonId = 16;\r", + " break;\r", + " case 'CLICK_TOUCHPAD':\r", + " buttonId = 17;\r", + " break;\r", + "\r", + " default:\r", + " console.error('The button: ' + button + ' in condition: \"Gamepad button pressed\" is not valid.');\r", + " eventsFunctionContext.returnValue = false;\r", + " break;\r", + "}\r", + "\r", + "\r", + "\r", + "if (buttonId === undefined) {\r", + " console.error('There is no buttons valid in condition: \"Gamepad button pressed\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "if (gamepad.buttons == null || gamepad.buttons[buttonId] == null) {\r", + " console.error('Buttons on the gamepad are not accessible in condition: \"Gamepad button pressed\"');\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "//When a button is pressed, save the button in lastButtonUsed for each players\r", + "if (gamepad.buttons[buttonId].pressed) gdjs._extensionController.players[playerId].lastButtonUsed = buttonId;\r", + "eventsFunctionContext.returnValue = gamepad.buttons[buttonId].pressed;\r", + "\r", + "\r", + "\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Name of the button", + "name": "button", + "supplementaryInformation": "[\"A\",\"Cross\",\"B\",\"Circle\",\"X\",\"Square\",\"Y\",\"Triangle\",\"LB\",\"L1\",\"RB\",\"R1\",\"LT\",\"L2\",\"RT\",\"R2\",\"Up\",\"Down\",\"Left\",\"Right\",\"Back\",\"Share\",\"Start\",\"Options\",\"Click_Stick_Left\",\"Click_Stick_Right\",\"PS_Button\",\"Click_Touchpad\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the value of the deadzone applied to a gamepad sticks, between 0 and 1.", + "fullName": "Gamepad deadzone for sticks", + "functionType": "Expression", + "name": "Deadzone", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//Get function parameter\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in expression: \"Gamepad deadzone for sticks\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "///Return the deadzone value for a given player\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.players[playerId].deadzone;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set the deadzone for sticks of the gamepad. The deadzone is an area for which movement on sticks won't be taken into account (instead, the stick will be considered as not moved). Deadzone is between 0 and 1, and is by default 0.2.", + "fullName": "Set gamepad deadzone for sticks", + "functionType": "Action", + "name": "A_Set_deadzone", + "sentence": "Set deadzone for sticks on gamepad: _PARAM1_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//Get function parameter\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const newDeadzone = eventsFunctionContext.getArgument(\"deadzone\");\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in action: \"Set gamepad deadzone for sticks\", is not valid, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "\r", + "// clamp the newDeadzone in range [0, 1].\r", + "// https://github.com/4ian/GDevelop-extensions/pull/33#issuecomment-618224857\r", + "gdjs._extensionController.players[playerId].deadzone = gdjs.evtTools.common.clamp(newDeadzone, 0, 1);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Deadzone for sticks, 0.2 by default (0 to 1)", + "name": "deadzone", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if a stick of a gamepad is pushed in a given direction.", + "fullName": "Gamepad stick pushed (axis)", + "functionType": "Condition", + "name": "C_Axis_pushed", + "sentence": "_PARAM2_ stick of gamepad _PARAM1_ is pushed in direction _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "const stick = eventsFunctionContext.getArgument(\"stick\").toUpperCase();\r", + "const direction = eventsFunctionContext.getArgument(\"direction\").toUpperCase();\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + " console.error('Parameter gamepad identifier in condition: \"Gamepad stick pushed (axis)\", is not valid number, must be between 0 and 4.');\r", + " return;\r", + "}\r", + "if (stick != \"LEFT\" && stick != \"RIGHT\") {\r", + " console.error('Parameter stick in condition: \"Gamepad stick pushed (axis)\", is not valid, must be LEFT or RIGHT');\r", + " return;\r", + "}\r", + "if (direction != \"UP\" && direction != \"DOWN\" && direction != \"LEFT\" && direction != \"RIGHT\" && direction != \"ANY\") {\r", + " console.error('Parameter deadzone in condition: \"Gamepad stick pushed (axis)\", is not valid, must be UP, DOWN, LEFT or RIGHT');\r", + " return;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) {\r", + " eventsFunctionContext.returnValue = false;\r", + " return;\r", + "}\r", + "\r", + "\r", + "//Define in onFirstSceneLoaded function\r", + "const getNormalizedAxisValue = gdjs._extensionController.getNormalizedAxisValue;\r", + "\r", + "switch (stick) {\r", + " case 'LEFT':\r", + " switch (direction) {\r", + " case 'LEFT':\r", + " if (getNormalizedAxisValue(gamepad.axes[0], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " if (getNormalizedAxisValue(gamepad.axes[0], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'UP':\r", + " if (getNormalizedAxisValue(gamepad.axes[1], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'DOWN':\r", + " if (getNormalizedAxisValue(gamepad.axes[1], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'ANY':\r", + " if ( getNormalizedAxisValue(gamepad.axes[0], playerId) < 0\r", + " || getNormalizedAxisValue(gamepad.axes[0], playerId) > 0\r", + " || getNormalizedAxisValue(gamepad.axes[1], playerId) < 0 \r", + " || getNormalizedAxisValue(gamepad.axes[1], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " default:\r", + " console.error('The value Direction on stick Left on the condition: \"Gamepad stick pushed (axis)\" is not valid.');\r", + " eventsFunctionContext.returnValue = false;\r", + " break;\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " switch (direction) {\r", + " case 'LEFT':\r", + " if (getNormalizedAxisValue(gamepad.axes[2], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'RIGHT':\r", + " if (getNormalizedAxisValue(gamepad.axes[2], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'UP':\r", + " if (getNormalizedAxisValue(gamepad.axes[3], playerId) < 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'DOWN':\r", + " if (getNormalizedAxisValue(gamepad.axes[3], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " case 'ANY':\r", + " if ( getNormalizedAxisValue(gamepad.axes[2], playerId) < 0\r", + " || getNormalizedAxisValue(gamepad.axes[2], playerId) > 0\r", + " || getNormalizedAxisValue(gamepad.axes[3], playerId) < 0 \r", + " || getNormalizedAxisValue(gamepad.axes[3], playerId) > 0) {\r", + " eventsFunctionContext.returnValue = true;\r", + " return;\r", + " }\r", + " break;\r", + "\r", + " default:\r", + " console.error('The value Direction on stick Right on the condition: \"Gamepad stick pushed (axis)\" is not valid.');\r", + " eventsFunctionContext.returnValue = false;\r", + " break;\r", + " }\r", + " break;\r", + "\r", + " default:\r", + " console.error('The value Stick on the condition: \"Gamepad stick pushed (axis)\" is not valid.');\r", + " eventsFunctionContext.returnValue = false;\r", + " break;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = false;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Stick: \"Left\" or \"Right\"", + "name": "stick", + "supplementaryInformation": "[\"Left\",\"Right\"]", + "type": "stringWithSelector" + }, + { + "description": "Direction", + "name": "direction", + "supplementaryInformation": "[\"Up\",\"Down\",\"Left\",\"Right\",\"Any\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of connected gamepads.", + "fullName": "Connected gamepads number", + "functionType": "Expression", + "name": "ConnectedGamepadsCount", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "// Gamepads can be disconnected and become null, so we have to filter them.\r", + "eventsFunctionContext.returnValue = Object.keys(gamepads).filter(key => !!gamepads[key]).length;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Return a string containing informations about the specified gamepad.", + "fullName": "Gamepad type", + "functionType": "StringExpression", + "name": "GamepadType", + "sentence": "Player _PARAM1_ use _PARAM2_ controller", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameter", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in string expression: \"Gamepad type\", is not valid number, must be between 0 and 4');", + " return;", + "}", + "", + "const gamepad = gamepads[playerId];", + "", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.", + "if (gamepad == null) return;", + "", + "eventsFunctionContext.returnValue = (gamepad && gamepad.id) ? gamepad.id : \"No information for player \" + (playerId + 1)", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the specified gamepad has the specified information in its description. Useful to know if the gamepad is a Xbox or PS4 controller.", + "fullName": "Gamepad type", + "functionType": "Condition", + "name": "C_Controller_type", + "sentence": "Gamepad _PARAM1_ is a _PARAM2_ controller", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameters", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;", + "const controllerType = eventsFunctionContext.getArgument(\"controller_type\").toUpperCase();", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in condition: \"Gamepad type\", is not valid number, must be between 0 and 4.');", + " return;", + "}", + "if (controllerType === \"\") {", + " console.error('Parameter type in condition: \"Gamepad type\", is not a string.');", + " return;", + "}", + "", + "const gamepad = gamepads[playerId];", + "", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.", + "if (gamepad == null) return;", + "", + "", + "if (controllerType == \"XBOX\") {", + " eventsFunctionContext.returnValue = gdjs._extensionController.isXbox(gamepad);", + "} else {", + " eventsFunctionContext.returnValue = gamepad ? gamepad.id.toUpperCase().indexOf(controllerType) !== -1 : false;", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + }, + { + "description": "Type: \"Xbox\", \"PS4\", \"Steam\" or \"PS3\" (among other)", + "name": "controller_type", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Check if a gamepad is connected.", + "fullName": "Gamepad connected", + "functionType": "Condition", + "name": "C_Controller_X_is_connected", + "sentence": "Gamepad _PARAM1_ is plugged and connected", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameter", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in condition: \"Gamepad connected\", is not valid number, must be between 0 and 4.');", + " return;", + "}", + "", + "// If gamepad was disconnected it will be null (so this will return false)", + "// If gamepad was never connected it will be undefined (so this will return false)", + "eventsFunctionContext.returnValue = !!gamepads[playerId];" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Generate a vibration on the specified controller. Might only work if the game is running in a recent web browser.", + "fullName": "Gamepad vibration", + "functionType": "Action", + "name": "A_Vibrate_controller", + "sentence": "Make gamepad _PARAM1_ vibrate for _PARAM2_ seconds", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "//Vibration work only on game in browser.", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameters", + "const playerId = eventsFunctionContext.getArgument(\"Player_ID\") - 1;", + "const duration = eventsFunctionContext.getArgument(\"Duration\") || 1;", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in action: \"Gamepad connected\", is not valid number, must be between 0 and 4.');", + " return;", + "}", + "", + "const gamepad = gamepads[playerId];", + "", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.", + "if (gamepad == null) return;", + "", + "if (gamepad && gamepad.vibrationActuator) {", + " gamepad.vibrationActuator.playEffect(\"dual-rumble\", {", + " startDelay: 0,", + " duration: duration * 1000,", + " weakMagnitude: 1.0,", + " strongMagnitude: 1.0", + " });", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Player_ID", + "type": "expression" + }, + { + "description": "Time of the vibration, in seconds (optional, default value is 1)", + "name": "Duration", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Generate an advanced vibration on the specified controller. Incompatible with Firefox.", + "fullName": "Advanced gamepad vibration", + "functionType": "Action", + "name": "A_Advanced_Vibration_Controller", + "sentence": "Make gamepad _PARAM1_ vibrate for _PARAM2_ seconds with the vibration magnitude of _PARAM3_ and _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "//Vibration work only on game in browser.", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameters", + "const playerId = eventsFunctionContext.getArgument(\"Player_ID\") - 1;", + "const duration = eventsFunctionContext.getArgument(\"Duration\") || 1;", + "const strongRumbleMagnitude = eventsFunctionContext.getArgument(\"StrongMagnitude\");", + "const weakRumbleMagnitude = eventsFunctionContext.getArgument(\"WeakMagnitude\");", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in action: \"Advanced gamepad vibration\", is not valid number, must be between 0 and 4.');", + " return;", + "}", + "if (weakRumbleMagnitude < 0 || weakRumbleMagnitude > 1) {", + " console.error('Parameter weakRumble identifier in action: \"Advanced gamepad vibration\", is not valid number, must be between 0 and 1.');", + " return;", + "}", + "if (strongRumbleMagnitude < 0 || strongRumbleMagnitude > 1) {", + " console.error('Parameter strongRumble identifier in action: \"Advanced gamepad vibration\", is not valid number, must be between 0 and 1.');", + " return;", + "}", + "", + "const gamepad = gamepads[playerId];", + "", + "//we need keep this condition because when use have not yet plug the controller we can't get the controller in the gamepad variable.", + "if (gamepad == null) return;", + "", + "if (gamepad && gamepad.vibrationActuator) {", + " gamepad.vibrationActuator.playEffect(\"dual-rumble\", {", + " startDelay: 0,", + " duration: duration * 1000,", + " weakMagnitude: weakRumbleMagnitude,", + " strongMagnitude: strongRumbleMagnitude", + " });", + "}", + "", + "gdjs._extensionController.players[playerId].rumble.duration = duration;", + "gdjs._extensionController.players[playerId].rumble.elapsedTime = 0;", + "gdjs._extensionController.players[playerId].rumble.weakMagnitude = weakRumbleMagnitude;", + "gdjs._extensionController.players[playerId].rumble.strongMagnitude = strongRumbleMagnitude;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Player_ID", + "type": "expression" + }, + { + "description": "Time of the vibration, in seconds (optional, default value is 1)", + "name": "Duration", + "type": "expression" + }, + { + "description": "Strong rumble magnitude (from 0 to 1)", + "name": "StrongMagnitude", + "type": "expression" + }, + { + "description": "Weak rumble magnitude (from 0 to 1)", + "name": "WeakMagnitude", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change a vibration on the specified controller. Incompatible with Firefox.", + "fullName": "Change gamepad active vibration", + "functionType": "Action", + "name": "A_Change_Vibration_Magnitude", + "sentence": "Change the vibration magnitude of _PARAM2_ & _PARAM3_ on gamepad _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */", + "//Vibration work only on game in browser.", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameters", + "const playerId = eventsFunctionContext.getArgument(\"Player_ID\") - 1;", + "const elapsedTime = gdjs._extensionController.players[playerId].rumble.elapsedTime || 0;", + "const originalDuration = gdjs._extensionController.players[playerId].rumble.duration || 1;", + "const strongRumbleMagnitude = eventsFunctionContext.getArgument(\"StrongMagnitude\");", + "const weakRumbleMagnitude = eventsFunctionContext.getArgument(\"WeakMagnitude\");", + "", + "", + "if (playerId < 0 || playerId > 4) {", + " console.error('Parameter gamepad identifier in action: \"Change gamepad active vibration\", is not valid number, must be between 0 and 4.');", + " return;", + "}", + "if (weakRumbleMagnitude < 0 || weakRumbleMagnitude > 1) {", + " console.error('Parameter weakRumble identifier in action: \"Change gamepad active vibration\", is not valid number, must be between 0 and 1.');", + " return;", + "}", + "if (strongRumbleMagnitude < 0 || strongRumbleMagnitude > 1) {", + " console.error('Parameter strongRumble identifier in action: \"Change gamepad active vibration\", is not valid number, must be between 0 and 1.');", + " return;", + "}", + "", + "const gamepad = gamepads[playerId];", + "", + "//we need keep this condition because when use have not yet plug the controller we can't get the controller in the gamepad variable.", + "if (gamepad == null) return;", + "", + "if (originalDuration - elapsedTime <= 0) return;", + "", + "if (gamepad && gamepad.vibrationActuator) {", + " gamepad.vibrationActuator.playEffect(\"dual-rumble\", {", + " startDelay: 0,", + " duration: 1000 * (originalDuration - elapsedTime),", + " weakMagnitude: weakRumbleMagnitude,", + " strongMagnitude: strongRumbleMagnitude", + " });", + "}", + "", + "gdjs._extensionController.players[playerId].rumble.weakMagnitude = weakRumbleMagnitude;", + "gdjs._extensionController.players[playerId].rumble.strongMagnitude = strongRumbleMagnitude;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Player_ID", + "type": "expression" + }, + { + "description": "Strong rumble magnitude (from 0 to 1)", + "name": "StrongMagnitude", + "type": "expression" + }, + { + "description": "Weak rumble magnitude (from 0 to 1)", + "name": "WeakMagnitude", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onFirstSceneLoaded", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//Define an new private object javascript for the gamepad extension\r", + "gdjs._extensionController = {\r", + " players: {\r", + " 0: { mapping: 'DEFAULT', lastButtonUsed: -1, deadzone: 0.2, previousFrameStateButtons: {}, rumble: {} },\r", + " 1: { mapping: 'DEFAULT', lastButtonUsed: -1, deadzone: 0.2, previousFrameStateButtons: {}, rumble: {} },\r", + " 2: { mapping: 'DEFAULT', lastButtonUsed: -1, deadzone: 0.2, previousFrameStateButtons: {}, rumble: {} },\r", + " 3: { mapping: 'DEFAULT', lastButtonUsed: -1, deadzone: 0.2, previousFrameStateButtons: {}, rumble: {} },\r", + " },\r", + " lastActiveController: -1, // Last active controller\r", + " controllerButtonNames: { //Map associating controller button ids to button names\r", + " \"XBOX\": {\r", + " 0: \"A\",\r", + " 1: \"B\",\r", + " 2: \"X\",\r", + " 3: \"Y\",\r", + " 4: \"LB\",\r", + " 5: \"RB\",\r", + " 6: \"LT\",\r", + " 7: \"RT\",\r", + " 8: \"BACK\",\r", + " 9: \"START\",\r", + " 10: \"CLICK_STICK_LEFT\",\r", + " 11: \"CLICK_STICK_RIGHT\",\r", + " 12: \"UP\",\r", + " 13: \"DOWN\",\r", + " 14: \"LEFT\",\r", + " 15: \"RIGHT\",\r", + " 16: \"NONE\",\r", + " 17: \"NONE\"\r", + " },\r", + " \"PS4\": {\r", + " 0: \"CROSS\",\r", + " 1: \"CIRCLE\",\r", + " 2: \"SQUARE\",\r", + " 3: \"TRIANGLE\",\r", + " 4: \"L1\",\r", + " 5: \"R1\",\r", + " 6: \"L2\",\r", + " 7: \"R2\",\r", + " 8: \"SHARE\",\r", + " 9: \"OPTIONS\",\r", + " 10: \"CLICK_STICK_LEFT\",\r", + " 11: \"CLICK_STICK_RIGHT\",\r", + " 12: \"UP\",\r", + " 13: \"DOWN\",\r", + " 14: \"LEFT\",\r", + " 15: \"RIGHT\",\r", + " 16: \"PS_BUTTON\",\r", + " 17: \"CLICK_TOUCHPAD\"\r", + " }\r", + " }\r", + "};\r", + "\r", + "gdjs._extensionController.getInputString = function (type, buttonId) {\r", + " const controllerButtonNames = gdjs._extensionController.controllerButtonNames;\r", + " if (controllerButtonNames[type] !== undefined) {\r", + " return controllerButtonNames[type][buttonId];\r", + " }\r", + "\r", + " return \"UNKNOWN_BUTTON\";\r", + "}\r", + "\r", + "gdjs._extensionController.axisToAngle = function (deltaX, deltaY) {\r", + " const rad = Math.atan2(deltaY, deltaX);\r", + " const deg = rad * (180 / Math.PI);\r", + " return deg;\r", + "}\r", + "\r", + "gdjs._extensionController.isXbox = function (gamepad) {\r", + " return (gamepad ? (\r", + " gamepad.id.toUpperCase().indexOf(\"XBOX\") !== -1\r", + " // \"XINPUT\" cannot be used to check if it is a xbox controller is just a generic\r", + " // name reported in Firefox corresponding to the driver being used by the controller\r", + " // https://gamefaqs.gamespot.com/boards/916373-pc/73341312?page=1\r", + " ) : false);\r", + "}\r", + "\r", + "//Returns the new value taking into account the dead zone for the player_ID given\r", + "gdjs._extensionController.getNormalizedAxisValue = function (v, player_ID) {\r", + " // gdjs._extensionController = gdjs._extensionController || { deadzone: 0.2 };\r", + "\r", + " // Anything smaller than this is assumed to be 0,0\r", + " const DEADZONE = gdjs._extensionController.players[player_ID].deadzone;\r", + "\r", + " if (Math.abs(v) < DEADZONE) {\r", + " // In the dead zone, set to 0\r", + " v = 0;\r", + "\r", + " if (v == null) {\r", + " return 0;\r", + " } else {\r", + " return v;\r", + " }\r", + "\r", + " } else {\r", + " // We're outside the dead zone, but we'd like to smooth\r", + " // this value out so it still runs nicely between 0..1.\r", + " // That is, we don't want it to jump suddenly from 0 to\r", + " // DEADZONE.\r", + "\r", + " // Remap v from\r", + " // DEADZONE..1 to 0..(1-DEADZONE)\r", + " // or from\r", + " // -1..-DEADZONE to -(1-DEADZONE)..0\r", + "\r", + " v = v - Math.sign(v) * DEADZONE;\r", + "\r", + " // Remap v from\r", + " // 0..(1-DEADZONE) to 0..1\r", + " // or from\r", + " // -(1-DEADZONE)..0 to -1..0\r", + "\r", + " return v / (1 - DEADZONE);\r", + " }\r", + "};" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onScenePostEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//Each time a player press a button i save the last button pressed for the next frame", + "/** @type {Gamepad[]} */", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);", + "", + "//Get function parameter", + "let countPlayers = Object.keys(gdjs._extensionController.players).length;", + "", + "//Repeat for each players", + "for (let i = 0; i < countPlayers; i++) {", + " let gamepad = gamepads[i]; // Get the gamepad of the player", + "", + " //We have to keep this condition because if the user hasn't plugged in his controller yet, we can't get the controller in the gamepad variable.", + " if (gamepad == null) {", + " continue;", + " }", + "", + " for (let b = 0; b < Object.keys(gamepad.buttons).length; b++) { //For each buttons", + " if (gamepad.buttons[b].pressed) { //One of them is pressed", + " gdjs._extensionController.players[i].lastButtonUsed = b; //Save the button pressed", + "", + " //Save the state of the button for the next frame.", + " gdjs._extensionController.players[i].previousFrameStateButtons[b] = { pressed: true };", + "", + " // Update Last Active Controller", + " gdjs._extensionController.lastActiveController = i;", + " } else {", + " gdjs._extensionController.players[i].previousFrameStateButtons[b] = { pressed: false };", + " }", + " }", + "", + "", + " gdjs._extensionController.players[i].rumble.elapsedTime += runtimeScene.getElapsedTime(runtimeScene) / 1000;", + " if (", + " gdjs._extensionController.players[i].rumble.duration - gdjs._extensionController.players[i].rumble.elapsedTime <= 0 &&", + " (gdjs._extensionController.players[i].rumble.weakMagnitude || gdjs._extensionController.players[i].rumble.strongMagnitude)", + " ) {", + " gdjs._extensionController.players[i].rumble.weakMagnitude = 0;", + " gdjs._extensionController.players[i].rumble.strongMagnitude = 0;", + " }", + "", + "", + "}", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Check if any button is released on a gamepad.", + "fullName": "Any gamepad button released", + "functionType": "Condition", + "name": "C_any_button_released", + "sentence": "Any button of gamepad _PARAM1_ is released", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Gamepad[]} */\r", + "const gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\r", + "\r", + "//Get function parameters\r", + "const playerId = eventsFunctionContext.getArgument(\"player_ID\") - 1;\r", + "\r", + "if (playerId < 0 || playerId > 4) {\r", + "\tconsole.error('Parameter gamepad identifier in condition: \"Any gamepad button released\", is not valid number, must be between 0 and 4.');\r", + "\treturn;\r", + "}\r", + "\r", + "const gamepad = gamepads[playerId];\r", + "\r", + "//we need keep this condition because when use have not yet plug her controller we can't get the controller in the gamepad variable.\r", + "if (gamepad == null) return;\r", + "\r", + "for (let buttonId = 0; buttonId < gamepad.buttons.length; buttonId++) { //For each buttons on current frame.\r", + "\r", + "\tif (buttonId === undefined) {\r", + "\t\teventsFunctionContext.returnValue = false;\r", + "\t\treturn;\r", + "\t}\r", + "\r", + "\t//Get previous value or define value by default for the current button\r", + "\tgdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId] = gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId] || { pressed: false };\r", + "\r", + "\t//Get state of the button at previous frame\r", + "\tconst previousStateButtonIsPressed = gdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed;\r", + "\r", + "\t//Get the state of the button on the current frame.\r", + "\tconst currentFrameStateButtonIsPressed = gamepad.buttons[buttonId].pressed;\r", + "\r", + "\t//When previousStateButtonIsPressed is true and actual button state is not pressed\r", + "\t//Player have release the button\r", + "\tif (previousStateButtonIsPressed === true && currentFrameStateButtonIsPressed === false) {\r", + "\t\tgdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed = true;\r", + "\t\teventsFunctionContext.returnValue = true;\r", + "\t\t//break;\r", + "\t\treturn;\r", + "\t} else {\r", + "\t\t//The player didn't released the button yet, the previous frame state is still true\r", + "\t\tgdjs._extensionController.players[playerId].previousFrameStateButtons[buttonId].pressed = false;\r", + "\t\teventsFunctionContext.returnValue = false;\r", + "\t}\r", + "\r", + "\tif (currentFrameStateButtonIsPressed) gdjs._extensionController.players[playerId].lastButtonUsed = buttonId;\r", + "}\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the strength of the weak vibration motor on the gamepad of a player.", + "fullName": "Weak rumble magnitude", + "functionType": "Expression", + "name": "WeakVibrationMagnitude", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const playerId = eventsFunctionContext.getArgument(\"Player_ID\") - 1;\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.players[playerId].rumble.weakMagnitude;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Player_ID", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the strength of the strong vibration motor on the gamepad of a player.", + "fullName": "Strong rumble magnitude", + "functionType": "Expression", + "name": "StrongVibrationMagnitude", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const playerId = eventsFunctionContext.getArgument(\"Player_ID\") - 1;\r", + "eventsFunctionContext.returnValue = gdjs._extensionController.players[playerId].rumble.strongMagnitude;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The gamepad identifier: 1, 2, 3 or 4", + "name": "Player_ID", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Control a platformer character with a gamepad.", + "fullName": "Platformer gamepad mapper", + "name": "PlatformerGamepadMapper", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Controller_X_is_connected" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseArrows" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Up\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + }, + { + "type": { + "value": "PlatformBehavior::SimulateLadderKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Down\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseLeftStick" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Left\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Right\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Up\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + }, + { + "type": { + "value": "PlatformBehavior::SimulateLadderKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Down\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseRightStick" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Left\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Right\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Up\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + }, + { + "type": { + "value": "PlatformBehavior::SimulateLadderKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Down\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"A or Cross\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"A\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"B or Circle\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"B\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"X or Square\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"X\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Y or Triangle\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Y\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"LB or L1\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"LB\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RB or R1\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"RB\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"LT or L2\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"LT\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyJumpButton" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RT or R2\"" + ] + }, + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"RT\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "PlatformerCharacter" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Gamepads::PlatformerGamepadMapper", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Platformer character behavior", + "description": "", + "group": "", + "extraInformation": [ + "PlatformBehavior::PlatformerObjectBehavior" + ], + "hidden": false, + "name": "PlatformerCharacter" + }, + { + "value": "1", + "type": "Number", + "label": "Gamepad identifier (1, 2, 3 or 4)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "GamepadIdentifier" + }, + { + "value": "true", + "type": "Boolean", + "label": "Use directional pad", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseArrows" + }, + { + "value": "true", + "type": "Boolean", + "label": "Use left stick", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseLeftStick" + }, + { + "value": "", + "type": "Boolean", + "label": "Use right stick", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseRightStick" + }, + { + "value": "A or Cross", + "type": "Choice", + "label": "Jump button", + "description": "", + "group": "Controls", + "extraInformation": [ + "A or Cross", + "B or Circle", + "X or Square", + "Y or Triangle", + "LB or L1", + "RB or R1", + "LT or L2", + "RT or R2" + ], + "hidden": false, + "name": "JumpButton" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Control a top-down character with a gamepad.", + "fullName": "Top-down gamepad mapper", + "name": "TopDownGamepadMapper", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Controller_X_is_connected" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseArrows" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Up\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Button_pressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Down\"", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseLeftStick" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Analog\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateStick" + }, + "parameters": [ + "Object", + "TopDownMovement", + "Gamepads::StickRotationValue(Object.Behavior::PropertyGamepadIdentifier(), \"Left\")", + "Gamepads::StickForce(Object.Behavior::PropertyGamepadIdentifier(), \"Left\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"360°\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateStick" + }, + "parameters": [ + "Object", + "TopDownMovement", + "Gamepads::StickRotationValue(Object.Behavior::PropertyGamepadIdentifier(), \"Left\")", + "sign(Gamepads::StickForce(Object.Behavior::PropertyGamepadIdentifier(), \"Left\"))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"8 Directions\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Left\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Right\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Up\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Left\"", + "\"Down\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::PlatformerGamepadMapper::PropertyUseRightStick" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Analog\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateStick" + }, + "parameters": [ + "Object", + "TopDownMovement", + "Gamepads::StickRotationValue(Object.Behavior::PropertyGamepadIdentifier(), \"Right\")", + "Gamepads::StickForce(Object.Behavior::PropertyGamepadIdentifier(), \"Right\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"360°\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateStick" + }, + "parameters": [ + "Object", + "TopDownMovement", + "sign(Gamepads::StickForce(Object.Behavior::PropertyGamepadIdentifier(), \"Right\"))", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::TopDownGamepadMapper::PropertyStickMode" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"8 Directions\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Left\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Right\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Up\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Gamepads::C_Axis_pushed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyGamepadIdentifier()", + "\"Right\"", + "\"Down\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "TopDownMovement" + ] + } + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Gamepads::TopDownGamepadMapper", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Top-down movement behavior", + "description": "", + "group": "", + "extraInformation": [ + "TopDownMovementBehavior::TopDownMovementBehavior" + ], + "hidden": false, + "name": "TopDownMovement" + }, + { + "value": "1", + "type": "Number", + "label": "Gamepad identifier (1, 2, 3 or 4)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "GamepadIdentifier" + }, + { + "value": "true", + "type": "Boolean", + "label": "Use directional pad", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseArrows" + }, + { + "value": "true", + "type": "Boolean", + "label": "Use left stick", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseLeftStick" + }, + { + "value": "", + "type": "Boolean", + "label": "Use right stick", + "description": "", + "group": "Controls", + "extraInformation": [], + "hidden": false, + "name": "UseRightStick" + }, + { + "value": "Analog", + "type": "Choice", + "label": "Stick mode", + "description": "", + "group": "Controls", + "extraInformation": [ + "Analog", + "360°", + "8 Directions" + ], + "hidden": false, + "name": "StickMode" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "Input", + "extensionNamespace": "", + "fullName": "Behavior Remapper", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWFscGhhLXctYm94LW91dGxpbmUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOSwxN0EyLDIgMCAwLDEgNywxNVY3SDlWMTVIMTFWOEgxM1YxNUgxNVY3SDE3VjE1QTIsMiAwIDAsMSAxNSwxN0g5TTUsM0gxOUEyLDIgMCAwLDEgMjEsNVYxOUEyLDIgMCAwLDEgMTksMjFINUEyLDIgMCAwLDEgMywxOVY1QTIsMiAwIDAsMSA1LDNNNSw1VjE5SDE5VjVINVoiIC8+PC9zdmc+", + "name": "BehaviorRemapper", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/alpha-w-box-outline.svg", + "shortDescription": "Quickly remap Behavior controls to different keys. ", + "version": "1.0.0", + "description": [ + "Make sure to disable default controls unless you want two keys to do the same action.", + "", + "Actions have two versions. `custom` allow the movement keys to be changed to what ever you would like. `presets` provide a common key-bindings that can be selected from a list.", + "", + "### Available Presets:", + "", + "##### `WASD`", + "-\tW: Up", + "-\tA: Left", + "-\tS: Down", + "-\tD: Right", + "-\tSpace: Jump", + "", + "##### `ZQSD`", + "-\tZ: Up", + "-\tQ: Left", + "-\tS: Down", + "-\tD: Right", + "-\tSpace: Jump", + "", + "##### `Numpad` (Num lock must be disabled)", + "-\tNumpad Up: Up", + "-\tNumpad Left: Left", + "-\tNumpad Down: Down", + "-\tNumpad Right: Right", + "-\tNumpad Return/Enter: Jump", + "", + "##### `IJKL`", + "-\tI: Up", + "-\tJ: Left", + "-\tK: Down", + "-\tL: Right", + "-\tReturn/Enter: Jump", + "" + ], + "origin": { + "identifier": "BehaviorRemapper", + "name": "gdevelop-extension-store" + }, + "tags": [ + "remapper", + "key", + "bindings", + "presets", + "platformer", + "top-down" + ], + "authorIds": [ + "AlZ3D1xkH0QDao7T37VZZUeYNpn1" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Allows for the controls of a Top-Down behavior to be re-mapped via a single action.", + "fullName": "Remap Top-down", + "name": "RemapForTopdown", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyUp()" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "Topdown" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyLeft()" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "Topdown" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyRight()" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "Topdown" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyDown()" + ] + } + ], + "actions": [ + { + "type": { + "value": "TopDownMovementBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "Topdown" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForTopdown", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Remaps Top-Down behavior controls to a custom control scheme.", + "fullName": "Remap Top-Down controls to a custom scheme", + "functionType": "Action", + "name": "SetCustom", + "sentence": "Remap controls of _PARAM0_: Up: _PARAM2_, Left: _PARAM3_, Down: _PARAM4_, Right: _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"up\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"left\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"right\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"down\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForTopdown", + "type": "behavior" + }, + { + "description": "Up key", + "name": "up", + "type": "key" + }, + { + "description": "Left key", + "name": "left", + "type": "key" + }, + { + "description": "Down key", + "name": "down", + "type": "key" + }, + { + "description": "Right key", + "name": "right", + "type": "key" + } + ], + "objectGroups": [] + }, + { + "description": "Remaps Top-Down behavior controls to a preset control scheme.", + "fullName": "Remap Top-Down controls to a preset", + "functionType": "Action", + "name": "SetPreset", + "sentence": "Remap controls of _PARAM0_ to preset _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "QWERTY bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"WASD\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"w\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"a\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"s\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"d\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "AZERTY bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"ZQSD\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"z\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"q\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"s\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"d\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Numpad bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"Numpad\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadUp\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadLeft\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadDown\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadRight\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "QWERTY player 2 bindings " + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"IJKL\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"i\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"j\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"k\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForTopdown::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"l\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForTopdown", + "type": "behavior" + }, + { + "description": "Preset name", + "name": "options", + "supplementaryInformation": "[\"WASD\",\"ZQSD\",\"Numpad\",\"IJKL\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "w", + "type": "String", + "label": "Up key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Up" + }, + { + "value": "a", + "type": "String", + "label": "Left key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Left" + }, + { + "value": "d", + "type": "String", + "label": "Right key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Right" + }, + { + "value": "s", + "type": "String", + "label": "Down key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Down" + }, + { + "value": "", + "type": "Behavior", + "label": "", + "description": "", + "group": "", + "extraInformation": [ + "TopDownMovementBehavior::TopDownMovementBehavior" + ], + "hidden": false, + "name": "Topdown" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Allows for the controls of a platformer behavior to be re-mapped via a single action.", + "fullName": "Remap Platformer controls", + "name": "RemapForPlatformer", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyUp()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateUpKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + }, + { + "type": { + "value": "PlatformBehavior::SimulateLadderKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyLeft()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateLeftKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyRight()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateRightKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyDown()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateDownKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + }, + { + "type": { + "value": "PlatformBehavior::SimulateReleaseLadderKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "KeyFromTextPressed" + }, + "parameters": [ + "", + "Object.Behavior::PropertyJump()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformBehavior::SimulateJumpKey" + }, + "parameters": [ + "Object", + "Platformer" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForPlatformer", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Remaps Platformer behavior controls to a custom control scheme.", + "fullName": "Remap Platformer controls to a custom scheme", + "functionType": "Action", + "name": "SetCustom", + "sentence": "Remap controls of _PARAM0_: Up: _PARAM2_, Left: _PARAM3_, Down: _PARAM4_, Right: _PARAM5_, Jump: _PARAM6_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"up\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"left\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"right\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"down\")" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyJump" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"jump\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForPlatformer", + "type": "behavior" + }, + { + "description": "Up key", + "name": "up", + "type": "key" + }, + { + "description": "Left key", + "name": "left", + "type": "key" + }, + { + "description": "Down key", + "name": "down", + "type": "key" + }, + { + "description": "Right key", + "name": "right", + "type": "key" + }, + { + "description": "Jump key", + "name": "jump", + "type": "key" + } + ], + "objectGroups": [] + }, + { + "description": "Remaps Platformer behavior controls to a preset control scheme.", + "fullName": "Remap Platformer controls to a preset", + "functionType": "Action", + "name": "SetPreset", + "sentence": "Remap controls of _PARAM0_ to preset _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "QWERTY bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"WASD\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"w\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"a\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"s\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"d\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyJump" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Space\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "AZERTY bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"ZQSD\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"z\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"q\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"s\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"d\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyJump" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Space\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Numpad bindings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"Numpad\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadUp\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadLeft\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadDown\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadRight\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyJump" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"NumpadReturn\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "QWERTY player 2 bindings " + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "GetArgumentAsString(\"options\")", + "=", + "\"IJKL\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyUp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"i\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"j\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyDown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"k\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"l\"" + ] + }, + { + "type": { + "value": "BehaviorRemapper::RemapForPlatformer::SetPropertyJump" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Return\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "BehaviorRemapper::RemapForPlatformer", + "type": "behavior" + }, + { + "description": "Preset name", + "name": "options", + "supplementaryInformation": "[\"WASD\",\"ZQSD\",\"Numpad\",\"IJKL\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "String", + "label": "Up key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Up" + }, + { + "value": "", + "type": "String", + "label": "Left key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Left" + }, + { + "value": "", + "type": "String", + "label": "Down key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Down" + }, + { + "value": "", + "type": "String", + "label": "Right key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Right" + }, + { + "value": "", + "type": "String", + "label": "Jump key", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Jump" + }, + { + "value": "", + "type": "Behavior", + "label": "", + "description": "", + "group": "", + "extraInformation": [ + "PlatformBehavior::PlatformerObjectBehavior" + ], + "hidden": false, + "name": "Platformer" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Platformer character animator", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPGc+DQoJPHBhdGggZD0iTTIzLDExYzIuMiwwLDQtMS44LDQtNHMtMS44LTQtNC00cy00LDEuOC00LDRTMjAuOCwxMSwyMywxMXoiLz4NCgk8cGF0aCBkPSJNMzAuOCwxMi40Yy0wLjMtMC40LTEtMC41LTEuNC0wLjJsLTIuOSwyLjNjLTAuOCwwLjctMiwwLjYtMi43LTAuMmwtNy45LTcuOWMtMS42LTEuNi00LjEtMS42LTUuNywwTDcuMyw5LjMNCgkJYy0wLjQsMC40LTAuNCwxLDAsMS40czEsMC40LDEuNCwwbDIuOC0yLjhjMC44LTAuOCwyLjEtMC44LDIuOSwwbDEuNiwxLjZMMTEuNiwxNGMtMSwxLTEuNCwyLjMtMS4xLDMuN2MwLjIsMS4xLDAuOSwyLDEuOCwyLjYNCgkJbC0xLjYsMS42Yy0wLjQsMC40LTEsMC40LTEuNCwwbC0zLjYtMy42Yy0wLjQtMC40LTEtMC40LTEuNCwwcy0wLjQsMSwwLDEuNGwzLjYsMy42YzAuNiwwLjYsMS4zLDAuOSwyLjEsMC45czEuNi0wLjMsMi4xLTAuOQ0KCQlsMi4xLTIuMWwyLjUsMWMwLjcsMC4zLDEuMiwxLDEuMiwxLjh2NmMwLDAuNiwwLjQsMSwxLDFzMS0wLjQsMS0xdi02YzAtMS42LTEtMy4xLTIuNS0zLjdsLTEuNy0wLjdsNS4yLTUuMmwxLjQsMS40DQoJCWMwLjgsMC44LDEuOCwxLjIsMi45LDEuMmMwLjksMCwxLjgtMC4zLDIuNS0wLjlsMi45LTIuM0MzMS4xLDEzLjQsMzEuMSwxMi44LDMwLjgsMTIuNHoiLz4NCjwvZz4NCjwvc3ZnPg0K", + "name": "PlatformerCharacterAnimator", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Glyphster Pack/Master/SVG/Sports and Fitness/Sports and Fitness_training_running_run.svg", + "shortDescription": "Change animations and horizontal flipping of a platformer character automatically.", + "version": "1.0.1", + "description": [ + "Automatically change the animations and horizontal flipping of a platformer character based on movement and interaction with platform objects.", + "", + "The platformer example uses this extension ([open the project online](https://editor.gdevelop.io/?project=example://platformer))." + ], + "origin": { + "identifier": "PlatformerCharacterAnimator", + "name": "gdevelop-extension-store" + }, + "tags": [ + "animations", + "platformer", + "flipping", + "automatic" + ], + "authorIds": [ + "gqDaZjCfevOOxBYkK6zlhtZnXCg1" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Change animations and horizontal flipping of a platformer character automatically.", + "fullName": "Platformer character animator", + "name": "PlatformerCharacterAnimator", + "objectType": "Sprite", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Flip character based on input from controls", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::PropertyEnableHorizontalFlipping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Left\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Right\"" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Right\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Left\"" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Change animations", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::PropertyEnableAnimationChanges" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsJumping" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyJumpAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsFalling" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyFallAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsOnFloor" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyRunAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyIdleAnimationName()" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsOnLadder" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyClimbAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "PlayAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "PauseAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::IsOnLadder" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "PlayAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onActivate", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Flip character based on input from controls", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::PropertyEnableHorizontalFlipping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Left\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Right\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Right\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsUsingControl" + }, + "parameters": [ + "Object", + "PlatformerBehavior", + "\"Left\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Change animations", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::PropertyEnableAnimationChanges" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsJumping" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyJumpAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsFalling" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyFallAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsOnFloor" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyRunAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyIdleAnimationName()" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::IsOnLadder" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyClimbAnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlayAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::PlatformerObjectBehavior::IsMovingEvenALittle" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PauseAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlatformBehavior::IsOnLadder" + }, + "parameters": [ + "Object", + "PlatformerBehavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlayAnimation" + }, + "parameters": [ + "Object" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Enable (or disable) automated animation changes a platformer character. Disabling animation changes is useful to play custom animations.", + "fullName": "Enable (or disable) automated animation changes", + "functionType": "Action", + "name": "EnableChangingAnimations", + "sentence": "Enable automated animation changes on _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyEnableAnimationChanges" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableAnimationChanges\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyEnableAnimationChanges" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "defaultValue": "yes", + "description": "Change animations automatically", + "name": "EnableAnimationChanges", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Enable (or disable) automated horizontal flipping of a platform character.", + "fullName": "Enable (or disable) automated horizontal flipping", + "functionType": "Action", + "name": "EnableHorizontalFlipping", + "sentence": "Enable automated horizontal flipping on _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyEnableHorizontalFlipping" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableHorizontalFlipping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyEnableHorizontalFlipping" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "defaultValue": "yes", + "description": "Enable horizontal flipping", + "name": "EnableHorizontalFlipping", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Set the \"Idle\" animation name. Do not use quotation marks.", + "fullName": "\"Idle\" animation name", + "functionType": "Action", + "group": "Configure animations", + "name": "SetIdleAnimationName", + "sentence": "Set \"Idle\" animation of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyIdleAnimationName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"AnimationName\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "description": "Animation name", + "name": "AnimationName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Set the \"Move\" animation name. Do not use quotation marks.", + "fullName": "\"Move\" animation name", + "functionType": "Action", + "group": "Configure animations", + "name": "SetMoveAnimationName", + "sentence": "Set \"Move\" animation of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyRunAnimationName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"AnimationName\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "description": "Animation name", + "name": "AnimationName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Set the \"Jump\" animation name. Do not use quotation marks.", + "fullName": "\"Jump\" animation name", + "functionType": "Action", + "group": "Configure animations", + "name": "SetJumpAnimationName", + "sentence": "Set \"Jump\" animation of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyJumpAnimationName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"AnimationName\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "description": "Animation name", + "name": "AnimationName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Set the \"Fall\" animation name. Do not use quotation marks.", + "fullName": "\"Fall\" animation name", + "functionType": "Action", + "group": "Configure animations", + "name": "SetFallAnimationName", + "sentence": "Set \"Fall\" animation of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyFallAnimationName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"AnimationName\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "description": "Animation name", + "name": "AnimationName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Set the \"Climb\" animation name. Do not use quotation marks.", + "fullName": "\"Climb\" animation name", + "functionType": "Action", + "group": "Configure animations", + "name": "SetClimbAnimationName", + "sentence": "Set \"Climb\" animation of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlatformerCharacterAnimator::PlatformerCharacterAnimator::SetPropertyClimbAnimationName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"AnimationName\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PlatformerCharacterAnimator::PlatformerCharacterAnimator", + "type": "behavior" + }, + { + "description": "Animation name", + "name": "AnimationName", + "type": "string" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "Enable animation changes", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "EnableAnimationChanges" + }, + { + "value": "true", + "type": "Boolean", + "label": "Enable horizontal flipping", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "EnableHorizontalFlipping" + }, + { + "value": "Idle", + "type": "String", + "label": "\"Idle\" animation name ", + "description": "", + "group": "Animation names", + "extraInformation": [], + "hidden": false, + "name": "IdleAnimationName" + }, + { + "value": "Run", + "type": "String", + "label": "\"Run\" animation name", + "description": "", + "group": "Animation names", + "extraInformation": [], + "hidden": false, + "name": "RunAnimationName" + }, + { + "value": "Jump", + "type": "String", + "label": "\"Jump\" animation name", + "description": "", + "group": "Animation names", + "extraInformation": [], + "hidden": false, + "name": "JumpAnimationName" + }, + { + "value": "Fall", + "type": "String", + "label": "\"Fall\" animation name", + "description": "", + "group": "Animation names", + "extraInformation": [], + "hidden": false, + "name": "FallAnimationName" + }, + { + "value": "Climb", + "type": "String", + "label": "\"Climb\" animation name", + "description": "", + "group": "Animation names", + "extraInformation": [], + "hidden": false, + "name": "ClimbAnimationName" + }, + { + "value": "", + "type": "Behavior", + "label": "Platformer character", + "description": "", + "group": "", + "extraInformation": [ + "PlatformBehavior::PlatformerObjectBehavior" + ], + "hidden": false, + "name": "PlatformerBehavior" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "Tristan Rhodes (https://victrisgames.itch.io/), D8H", + "category": "Input", + "extensionNamespace": "", + "fullName": "Draggable slider", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPGNpcmNsZSBjbGFzcz0ic3QwIiBjeD0iMjMiIGN5PSI3IiByPSIzIi8+DQo8bGluZSBjbGFzcz0ic3QwIiB4MT0iMyIgeTE9IjciIHgyPSIyMCIgeTI9IjciLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIyOSIgeTE9IjciIHgyPSIyNiIgeTI9IjciLz4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjEyIiBjeT0iMTYiIHI9IjMiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIzIiB5MT0iMTYiIHgyPSI5IiB5Mj0iMTYiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIyOSIgeTE9IjE2IiB4Mj0iMTUiIHkyPSIxNiIvPg0KPGNpcmNsZSBjbGFzcz0ic3QwIiBjeD0iMjMiIGN5PSIyNSIgcj0iMyIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjMiIHkxPSIyNSIgeDI9IjIwIiB5Mj0iMjUiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIyOSIgeTE9IjI1IiB4Mj0iMjYiIHkyPSIyNSIvPg0KPC9zdmc+DQo=", + "name": "DraggableSliderControl", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/UI Essentials/UI Essentials_sliders_options.svg", + "shortDescription": "A draggable slider that users can move to select a numerical value.", + "version": "1.0.5", + "description": [ + "Draws a draggable slider that users can move to select a numerical value.", + "The value range, tick spacing, and the appearance of the slider can be defined with properties.", + "", + "How to use:", + "- Add this behavior a **Shape Painter** object", + "- Place an instance of that shape painter on the screen where you want the slider to appear", + "- Use the \"Value\" expression to find the Value based on the position of the slider", + "", + "Tips:", + "- You can disable the slider to prevent a user from interacting with it", + "- You can set the Value of the slider and the slider will move to the correct position", + "", + "Further details can be found in [this tutorial video](https://youtu.be/iiTUwdAT_hs).", + "", + "Breaking changes (1.0.0)", + "- Track thickness and length properties replaced track width and height. These 2 properties must be set again if they were different from the default size.", + "- Hidden sliders can be dragged. The \"enable\" action must be used to disable them.", + "" + ], + "origin": { + "identifier": "DraggableSliderControl", + "name": "gdevelop-extension-store" + }, + "tags": [ + "draggable", + "slider", + "shape painter", + "ui", + "widget" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2", + "gqDaZjCfevOOxBYkK6zlhtZnXCg1" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Let users select a numerical value by dragging a slider.", + "fullName": "Draggable slider", + "name": "DraggableSliderControl", + "objectType": "PrimitiveDrawing::Drawer", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure object doesn't get re-drawn every frame" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::ClearBetweenFrames" + }, + "parameters": [ + "Object", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Use correct min value (instead of always starting at 0)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyValueMin()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set track height function (which enforces valid thumb sizes)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTrackThickness" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyTrackThickness()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Start halo at same size as thumb" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::PropertyThumbHeight()/2,Object.Behavior::PropertyThumbWidth()/2)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::UpdateHitbox" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Slider logic", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::IsEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Track where the mouse is (in relation to object)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyMouseX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.ToDrawingX(MouseX(Object.Layer(), 0), MouseY(Object.Layer(), 0))" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyMouseY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.ToDrawingY(MouseX(Object.Layer(), 0), MouseY(Object.Layer(), 0))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move slider when being dragged" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbOffset" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyMouseX()" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "End sliding and update variables" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "MouseButtonReleased" + }, + "parameters": [ + "", + "Left" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update \"Value\" based on the location of the thumb" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetValue" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyValueMin() + (Object.Behavior::PropertyValueMax() - Object.Behavior::PropertyValueMin()) * Object.Behavior::PropertyThumbOffset() / Object.Behavior::PropertyTrackLength()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Grow halo even more when pressed" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTargetHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1.25 * Object.Behavior::PropertyHaloRadius()" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Detect hover/touch/click (but only if the layer and object is visible, and the object is not already being dragged)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Detect mouse clicks near track, start dragging" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SourisBouton" + }, + "parameters": [ + "", + "Left" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseX()", + ">=", + "-Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseX()", + "<=", + "Object.Behavior::PropertyTrackLength() + Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseY()", + ">=", + "-Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseY()", + "<=", + "Object.Behavior::PropertyHaloRadius()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Reset hover detection " + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyIsHovered" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Grow halo when hovered" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "SourisBouton" + }, + "parameters": [ + "", + "Left" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseX()", + ">=", + "Object.Behavior::PropertyThumbOffset() - Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseX()", + "<=", + "Object.Behavior::PropertyThumbOffset() + Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseY()", + ">=", + "- Object.Behavior::PropertyHaloRadius()" + ] + }, + { + "type": { + "value": "Egal" + }, + "parameters": [ + "Object.Behavior::PropertyMouseY()", + "<=", + "Object.Behavior::PropertyHaloRadius()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyIsHovered" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTargetHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyHaloRadius()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Shrink halo to zero when not hovered" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsHovered" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTargetHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::PropertyThumbHeight(), Object.Behavior::PropertyThumbWidth()) / 2" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "Object.Behavior::PropertyTargetHaloRadius()" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Redraw slider only when halo is not at final size" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "abs(Object.Behavior::PropertyCurrentHaloRadius() - Object.Behavior::PropertyTargetHaloRadius())", + "<", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyTargetHaloRadius()" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "Object.Behavior::PropertyTargetHaloRadius()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "lerp(Object.Behavior::PropertyCurrentHaloRadius(), Object.Behavior::PropertyTargetHaloRadius(), Object.Behavior::PropertyHaloGrowSpeed())" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Slider drawing", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "Visible" + }, + "parameters": [ + "Object" + ] + }, + { + "type": { + "value": "LayerVisible" + }, + "parameters": [ + "", + "Object.Layer()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::Drawer::ClearShapes" + }, + "parameters": [ + "Object" + ] + } + ], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Inactive track", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set inactive track parameters (by default, use thumb color)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyInactiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbColor()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyInactiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "\"\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyInactiveTrackColor()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyInactiveTrackOpacity()" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::OutlineOpacity" + }, + "parameters": [ + "Object", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw inactive track" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Rectangle" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbOffset()", + "-Object.Behavior::PropertyTrackThickness() / 2", + "Object.Behavior::PropertyTrackLength()", + "Object.Behavior::PropertyTrackThickness() / 2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw half circle at end of track (inactive side)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyRoundedTrack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Arc" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyTrackLength()", + "0", + "Object.Behavior::PropertyTrackThickness() / 2", + "270", + "90", + "", + "yes" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Active track", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set active track parameters (by default, use thumb color)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyActiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbColor()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyActiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "\"\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyActiveTrackColor()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyActiveTrackOpacity()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw active track (2 pixels bigger than property) " + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Rectangle" + }, + "parameters": [ + "Object", + "0", + "-(Object.Behavior::PropertyTrackThickness() / 2 + 1)", + "Object.Behavior::PropertyThumbOffset()", + "Object.Behavior::PropertyTrackThickness() / 2 + 1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw half circle at end of track (active side)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyRoundedTrack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Arc" + }, + "parameters": [ + "Object", + "0", + "0", + "1 + Object.Behavior::PropertyTrackThickness() / 2", + "90", + "270", + "", + "yes" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Halo", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyCurrentHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "min(Object.Behavior::PropertyThumbHeight(), Object.Behavior::PropertyThumbWidth()) / 2" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Prepare halo" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbColor()" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::OutlineOpacity" + }, + "parameters": [ + "Object", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw halo (it will grow or shrink as needed)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyHaloOpacityHover()" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::Circle" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbOffset()", + "0", + "Object.Behavior::PropertyCurrentHaloRadius()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Use a more opaque halo while being dragged (it will grow or shrink as needed)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyHaloOpacityClick()" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::Circle" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbOffset()", + "0", + "Object.Behavior::PropertyCurrentHaloRadius()" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Thumb", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Prepare thumb settings" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::FillColor" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbColor()" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyThumbOpacity()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw Circle thumb" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbShape" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"circle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Circle" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbOffset()", + "0", + "ceil(max(Object.Behavior::PropertyThumbWidth(),Object.Behavior::PropertyThumbHeight())/2)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Draw Rectangle thumb" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbShape" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"rectangle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::Rectangle" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyThumbOffset() - (Object.Behavior::PropertyThumbWidth() / 2)", + "-Object.Behavior::PropertyThumbHeight() / 2", + "Object.Behavior::PropertyThumbOffset() + (Object.Behavior::PropertyThumbWidth() / 2)", + "Object.Behavior::PropertyThumbHeight() / 2" + ] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the slider is being dragged.", + "fullName": "Being dragged", + "functionType": "Condition", + "group": "Slider", + "name": "IsBeingDragged", + "sentence": "_PARAM0_ is being dragged", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the slider interactions are enabled.", + "fullName": "Interactions enabled", + "functionType": "Condition", + "group": "Slider", + "name": "IsEnabled", + "sentence": "Interactions of _PARAM0_ are enabled", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyEnabled" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Enable or disable the slider. Users cannot interact while it is disabled.", + "fullName": "Enable interactions", + "functionType": "Action", + "group": "Slider", + "name": "SetEnabled", + "sentence": "Enable interactions of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Enable\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Stop dragging (so the slider won't be dragging when it gets enabled)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyIsBeingDragged" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Reset halo size (so halo won't appear when slider gets enabled)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTargetHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::PropertyThumbHeight(), Object.Behavior::PropertyThumbWidth()) / 2" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Enable\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Enable", + "name": "Enable", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "The value of the slider (based on position of the thumb).", + "fullName": "Slider value", + "functionType": "Expression", + "group": "Slider", + "name": "Value", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyValue()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the value of a slider (this will move the thumb to the correct position).", + "fullName": "Slider value", + "functionType": "Action", + "group": "Slider", + "name": "SetValue", + "sentence": "Change the value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyTickSpacing" + }, + "parameters": [ + "Object", + "Behavior", + "<=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyTickSpacing" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "round(GetArgumentAsNumber(\"Value\") / Object.Behavior::PropertyTickSpacing()) * Object.Behavior::PropertyTickSpacing()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyValueMin()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyValueMin()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "Object.Behavior::PropertyValueMax()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValue" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyValueMax()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set the proper offset (it moves the slider)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbOffset" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyTrackLength() * (Object.Behavior::PropertyValue() - Object.Behavior::PropertyValueMin()) / (Object.Behavior::PropertyValueMax() - Object.Behavior::PropertyValueMin())" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Slider value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The minimum value of a slider.", + "fullName": "Slider minimum value", + "functionType": "Expression", + "group": "Slider value configuration", + "name": "ValueMin", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyValueMin()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the minimum value of a slider.", + "fullName": "Slider minimum value", + "functionType": "Action", + "group": "Slider value configuration", + "name": "SetValueMin", + "sentence": "Change the minimum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValueMin" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"ValueMin\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetValue" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::Value()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Minimum value", + "name": "ValueMin", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The maximum value of a slider.", + "fullName": "Slider maximum value", + "functionType": "Expression", + "group": "Slider value configuration", + "name": "ValueMax", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyValueMax()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Thickness of track.", + "fullName": "Slider track thickness", + "functionType": "Expression", + "group": "Slider track configuration", + "name": "TrackThickness", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTrackThickness()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Length of track.", + "fullName": "Slider track length", + "functionType": "Expression", + "group": "Slider track configuration", + "name": "TrackLength", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTrackLength()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Height of thumb.", + "fullName": "Slider thumb height", + "functionType": "Expression", + "group": "Slider thumb configuration", + "name": "ThumbHeight", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyThumbHeight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the maximum value of a slider.", + "fullName": "Slider maximum value", + "functionType": "Action", + "group": "Slider value configuration", + "name": "SetValueMax", + "sentence": "Change the maximum value of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyValueMax" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"ValueMax\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetValue" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::Value()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Maximum value", + "name": "ValueMax", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The tick spacing of a slider.", + "fullName": "Tick spacing", + "functionType": "Expression", + "group": "Slider value configuration", + "name": "TickSpacing", + "sentence": "Change the tick spacing of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTickSpacing()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Tick spacing", + "name": "TickSpacing", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the tick spacing of a slider.", + "fullName": "Tick spacing", + "functionType": "Action", + "group": "Slider value configuration", + "name": "SetTickSpacing", + "sentence": "Change the tick spacing of _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTickSpacing" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"TickSpacing\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetValue" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::Value()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Tick spacing", + "name": "TickSpacing", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change length of track.", + "fullName": "Track length", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetTrackLength", + "sentence": "Change track length of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTrackLength" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::UpdateHitbox" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move thumb to correct place (based on new track size)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetValue" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyValue()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Track width", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change thickness of track.", + "fullName": "Track thickness", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetTrackThickness", + "sentence": "Change track thickness of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyTrackThickness" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure thumb width is not smaller than track height + 2 pixels (to prevent track ends from showing)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbWidth" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyTrackThickness() + 2" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetThumbWidth" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyTrackThickness() + 2", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbHeight" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyTrackThickness() + 2" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetThumbHeight" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyTrackThickness() + 2", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Track thickness", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change width of thumb.", + "fullName": "Thumb width", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetThumbWidth", + "sentence": "Change thumb width of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Thumb cannot be less than track thickness (plus 2 pixels)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbWidth" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(GetArgumentAsNumber(\"Value\"), Object.Behavior::PropertyTrackThickness() + 2)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::UpdateHitbox" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Thumb width", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change height of thumb.", + "fullName": "Thumb height", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetThumbHeight", + "sentence": "Change thumb height of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Thumb cannot be less than track thickness (plus 2 pixels)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbHeight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(GetArgumentAsNumber(\"Value\"), Object.Behavior::PropertyTrackThickness() + 2)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::UpdateHitbox" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Thumb height", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change radius of the halo around the thumb. This size is also used to detect interaction with the slider.", + "fullName": "Halo radius", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetHaloRadius", + "sentence": "Change halo radius of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyHaloRadius" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Halo radius", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the halo opacity when the thumb is hovered.", + "fullName": "Halo opacity (hover)", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetHaloOpacityHover", + "sentence": "Change the halo opacity when hovered of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyHaloOpacityHover" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Halo opacity (hover)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change opacity of halo when pressed.", + "fullName": "Halo opacity (pressed)", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetHaloOpacityPressed", + "sentence": "Change halo opacity when pressed of _PARAM0_ to _PARAM2_ px", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyHaloOpacityClick" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Halo opacity (pressed)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change shape of thumb (circle or rectangle).", + "fullName": "Thumb shape", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetThumbShape", + "sentence": "Change shape of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbShape" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Shape\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure thumb width is not smaller than track height (to prevent track ends from showing)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbShape" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"rectangle\"" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::PropertyThumbWidth" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyTrackThickness()" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetThumbWidth" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::PropertyTrackThickness()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "New thumb shape", + "name": "Shape", + "supplementaryInformation": "[\"circle\",\"rectangle\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Make track use rounded ends.", + "fullName": "Rounded track ends", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetRoundedTrack", + "sentence": "Draw _PARAM0_ with a rounded track: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "GetArgumentAsNumber(\"Value\")", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyRoundedTrack" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "GetArgumentAsNumber(\"Value\")", + "=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyRoundedTrack" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Rounded track", + "name": "Value", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Change opacity of thumb.", + "fullName": "Thumb opacity", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetThumbOpacity", + "sentence": "Change thumb opacity of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbOpacity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Thumb opacity", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change opacity of inactive track.", + "fullName": "Inactive track opacity", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetInactiveTrackOpacity", + "sentence": "Change inactive track opacity of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyInactiveTrackOpacity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Inactive track opacity", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change opacity of active track.", + "fullName": "Active track opacity", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetActiveTrackOpacity", + "sentence": "Change active track opacity of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyActiveTrackOpacity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Active track opacity", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the color of the track that is LEFT of the thumb.", + "fullName": "Active track color ", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetActiveTrackColor", + "sentence": "Change active track color of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyActiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Color\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Active track color", + "name": "Color", + "type": "color" + } + ], + "objectGroups": [] + }, + { + "description": "Change the color of the track that is RIGHT of the thumb.", + "fullName": "Inactive track color", + "functionType": "Action", + "group": "Slider track configuration", + "name": "SetInactiveTrackColor", + "sentence": "Change inactive track color of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyInactiveTrackColor" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Color\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Inactive track color", + "name": "Color", + "type": "color" + } + ], + "objectGroups": [] + }, + { + "description": "Change the thumb color to a specific value.", + "fullName": "Thumb color", + "functionType": "Action", + "group": "Slider thumb configuration", + "name": "SetThumbColor", + "sentence": "Change thumb color of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyThumbColor" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsString(\"Color\")" + ] + }, + { + "type": { + "value": "DraggableSliderControl::DraggableSliderControl::SetPropertyNeedRedraw" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + }, + { + "description": "Thumb color", + "name": "Color", + "type": "color" + } + ], + "objectGroups": [] + }, + { + "description": "Update the hitbox.", + "fullName": "Update hitbox", + "functionType": "Action", + "group": "Private", + "name": "UpdateHitbox", + "private": true, + "sentence": "Update the hitbox of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::SetRotationCenter" + }, + "parameters": [ + "Object", + "Object.Behavior::PropertyTrackLength() / 2", + "Object.Behavior::PropertyTrackThickness() / 2" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::SetRectangularCollisionMask" + }, + "parameters": [ + "Object", + "-Object.Behavior::PropertyThumbWidth() / 2", + "-Object.Behavior::PropertyThumbHeight() / 2", + "Object.Behavior::PropertyTrackLength() + Object.Behavior::PropertyThumbWidth() / 2", + "Object.Behavior::PropertyThumbHeight() / 2" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "DraggableSliderControl::DraggableSliderControl", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "0", + "type": "Number", + "label": "Minimum value", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "ValueMin" + }, + { + "value": "1", + "type": "Number", + "label": "Maximum value", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "ValueMax" + }, + { + "value": "0", + "type": "Number", + "label": "Tick spacing", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "TickSpacing" + }, + { + "value": "circle", + "type": "Choice", + "label": "Thumb shape", + "description": "", + "group": "Thumb", + "extraInformation": [ + "circle", + "rectangle" + ], + "hidden": false, + "name": "ThumbShape" + }, + { + "value": "20", + "type": "Number", + "label": "Thumb width", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "ThumbWidth" + }, + { + "value": "20", + "type": "Number", + "label": "Thumb height", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "ThumbHeight" + }, + { + "value": " 24;119;211", + "type": "Color", + "label": "Thumb Color", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "ThumbColor" + }, + { + "value": "255", + "type": "Number", + "label": "Thumb opacity", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "ThumbOpacity" + }, + { + "value": "200", + "type": "Number", + "label": "Track length", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "TrackLength" + }, + { + "value": "4", + "type": "Number", + "label": "Track thickness", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "TrackThickness" + }, + { + "value": "", + "type": "String", + "label": "Inactive track color (thumb color by default)", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "InactiveTrackColor" + }, + { + "value": "96", + "type": "Number", + "label": "Inactive track opacity", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "InactiveTrackOpacity" + }, + { + "value": " ", + "type": "String", + "label": "Active track color (thumb color by default)", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "ActiveTrackColor" + }, + { + "value": "255", + "type": "Number", + "label": "Active track opacity", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "ActiveTrackOpacity" + }, + { + "value": "24", + "type": "Number", + "label": "Halo size (hover)", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "HaloRadius" + }, + { + "value": "32", + "type": "Number", + "label": "Halo opacity (hover)", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "HaloOpacityHover" + }, + { + "value": "64", + "type": "Number", + "label": "Halo opacity (pressed)", + "description": "", + "group": "Thumb", + "extraInformation": [], + "hidden": false, + "name": "HaloOpacityClick" + }, + { + "value": "true", + "type": "Boolean", + "label": "Rounded track ends", + "description": "", + "group": "Track", + "extraInformation": [], + "hidden": false, + "name": "RoundedTrack" + }, + { + "value": "true", + "type": "Boolean", + "label": "Enable interactions", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Enabled" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsBeingDragged" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Value" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ThumbOffset" + }, + { + "value": "true", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "NeedRedraw" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsHovered" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MouseX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MouseY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CurrentHaloRadius" + }, + { + "value": "0.2", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "HaloGrowSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TargetHaloRadius" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "@4ian, Tristan Rhodes (https://victrisgames.itch.io/)", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Rectangular movement", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXNoYXBlLXJlY3RhbmdsZS1wbHVzIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTE5LDZIMjJWOEgxOVYxMUgxN1Y4SDE0VjZIMTdWM0gxOVY2TTE3LDE3VjE0SDE5VjE5SDNWNkgxMVY4SDVWMTdIMTdaIiAvPjwvc3ZnPg==", + "name": "RectangleMovement", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/shape-rectangle-plus.svg", + "shortDescription": "Move objects in a rectangular pattern.", + "version": "1.1.0", + "description": [ + "Move objects in a rectangular pattern with easing functions from the Tween extension.", + "", + "It can be used for:", + "- Moveable platforms", + "- Enemy movement patterns", + "- Moving along the border of another object", + "", + "The platformer example uses this extension ([open the project online](https://editor.gdevelop.io/?project=example://platformer)).", + "", + "This example can be used to check some settings ([open the project online](https://editor.gdevelop.io/?project=example://rectangular-movement))." + ], + "origin": { + "identifier": "RectangleMovement", + "name": "gdevelop-extension-store" + }, + "tags": [ + "rectangular", + "movement", + "rectangle", + "patrol", + "platform", + "enemy" + ], + "authorIds": [ + "wWP8BSlAW0UP4NeaHa2LcmmDzmH2", + "gqDaZjCfevOOxBYkK6zlhtZnXCg1", + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Distance from an object to the closest edge of a second object.", + "fullName": "Distance from an object to the closest edge of a second object", + "functionType": "Expression", + "name": "DistanceToClosestEdge", + "private": true, + "sentence": "Distance from _PARAM1_ to the closest edge of _PARAM2_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "If point is inside rectangle, just use min distance" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CenterX" + }, + "parameters": [ + "MovingObject", + ">=", + "CenterObject.BoundingBoxLeft()" + ] + }, + { + "type": { + "value": "CenterX" + }, + "parameters": [ + "MovingObject", + "<=", + "CenterObject.BoundingBoxRight()" + ] + }, + { + "type": { + "value": "CenterY" + }, + "parameters": [ + "MovingObject", + ">=", + "CenterObject.BoundingBoxTop()" + ] + }, + { + "type": { + "value": "CenterY" + }, + "parameters": [ + "MovingObject", + "<=", + "CenterObject.BoundingBoxBottom()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "min(\nmin(\nMovingObject.BoundingBoxCenterY() - CenterObject.BoundingBoxTop(), \nCenterObject.BoundingBoxBottom() - MovingObject.BoundingBoxCenterY()),\nmin(\nMovingObject.BoundingBoxCenterX() - CenterObject.BoundingBoxLeft(), \nCenterObject.BoundingBoxRight() - MovingObject.BoundingBoxCenterX())\n)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "If point is outside rectangle, find distance to clamped position on rectangle" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CenterX" + }, + "parameters": [ + "MovingObject", + "<", + "CenterObject.BoundingBoxLeft()" + ] + }, + { + "type": { + "value": "CenterX" + }, + "parameters": [ + "MovingObject", + ">", + "CenterObject.BoundingBoxRight()" + ] + }, + { + "type": { + "value": "CenterY" + }, + "parameters": [ + "MovingObject", + "<", + "CenterObject.BoundingBoxTop()" + ] + }, + { + "type": { + "value": "CenterY" + }, + "parameters": [ + "MovingObject", + ">", + "CenterObject.BoundingBoxBottom()" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "DistanceBetweenPositions(\nMovingObject.BoundingBoxCenterX(),\nMovingObject.BoundingBoxCenterY(),\nclamp(MovingObject.BoundingBoxCenterX(), CenterObject.BoundingBoxLeft(), CenterObject.BoundingBoxRight()),\nclamp(MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxTop(), CenterObject.BoundingBoxBottom())\n)" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Center object", + "name": "CenterObject", + "type": "objectList" + }, + { + "description": "Moving object", + "name": "MovingObject", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Update rectangular movement to follow the border of an object. Run once, or every time the center object moves.", + "fullName": "Update rectangular movement to follow the border of an object", + "functionType": "Action", + "name": "MoveAlongBorderOfObject", + "sentence": "Update rectangular movement of _PARAM1_ to follow the border of _PARAM3_", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Create object link (if one has not been created)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectVariableAsBoolean" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.Linked", + "False" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Set a valid initial value by picking any Center object", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "MovingObject", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.DistanceToClosestEdge", + "=", + "RectangleMovement::DistanceToClosestEdge(CenterObject, MovingObject)" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update value if distance is lower than existing minimum", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "CenterObject", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.DistanceToClosestEdge", + "=", + "min(MovingObject.Variable(__RectangleMovement.DistanceToClosestEdge), RectangleMovement::DistanceToClosestEdge(CenterObject, MovingObject))" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Link objects that have the closest distance", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "CenterObject", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Link the MovingObject that has the shortest distance (and don't create more links even if another object has the same distance)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectVariableAsBoolean" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.Linked", + "False" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "RectangleMovement::DistanceToClosestEdge(CenterObject, MovingObject)", + "=", + "MovingObject.Variable(__RectangleMovement.DistanceToClosestEdge)" + ] + } + ], + "actions": [ + { + "type": { + "value": "LinkedObjects::LinkObjects" + }, + "parameters": [ + "", + "MovingObject", + "CenterObject" + ] + }, + { + "type": { + "value": "SetObjectVariableAsBoolean" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.Linked", + "True" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update rectangular movement to follow the border of object", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "CenterObject", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "MovingObject", + "CenterObject", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetTop" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "CenterObject.BoundingBoxTop()", + "" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetBottom" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "CenterObject.BoundingBoxBottom()", + "" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetLeft" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "CenterObject.BoundingBoxLeft()", + "" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetRight" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "CenterObject.BoundingBoxRight()", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Moving object", + "name": "MovingObject", + "type": "objectList" + }, + { + "description": "Rectangle Movement (required)", + "name": "RectangleMovement", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Center object", + "name": "CenterObject", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Move to the nearest corner of the center object.", + "fullName": "Move to the nearest corner of the center object", + "functionType": "Action", + "name": "MoveToNearestCorner", + "sentence": "Move _PARAM1_ to the nearest corner of _PARAM3_", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Create a link to the closest object", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectVariableAsBoolean" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.Linked", + "False" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::MoveAlongBorderOfObject" + }, + "parameters": [ + "", + "MovingObject", + "RectangleMovement", + "CenterObject", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move to nearest corner", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "MovingObject", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "CenterObject", + "MovingObject", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Distance to TopLeft (don't use a condition on the first check so the variable starts with a valid corner)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.ClosestCornerDistance", + "=", + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxLeft(), CenterObject.BoundingBoxTop())" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::TeleportToCorner" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "\"Top-left corner\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Distance to TopRight" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxRight(), CenterObject.BoundingBoxTop())", + "<", + "MovingObject.Variable(__RectangleMovement.ClosestCornerDistance)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.ClosestCornerDistance", + "=", + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxRight(), CenterObject.BoundingBoxTop())" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::TeleportToCorner" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "\"Top-right corner\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Distance to BottomLeft" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxLeft(), CenterObject.BoundingBoxBottom())", + "<", + "MovingObject.Variable(__RectangleMovement.ClosestCornerDistance)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.ClosestCornerDistance", + "=", + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxLeft(), CenterObject.BoundingBoxBottom())" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::TeleportToCorner" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "\"Bottom-left corner\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Distance to BottomRight" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxRight(), CenterObject.BoundingBoxBottom())", + "<", + "MovingObject.Variable(__RectangleMovement.ClosestCornerDistance)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "MovingObject", + "__RectangleMovement.ClosestCornerDistance", + "=", + "DistanceBetweenPositions(MovingObject.BoundingBoxCenterX(), MovingObject.BoundingBoxCenterY(), CenterObject.BoundingBoxRight(), CenterObject.BoundingBoxBottom())" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::TeleportToCorner" + }, + "parameters": [ + "MovingObject", + "RectangleMovement", + "\"Bottom-right corner\"", + "" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Moving object", + "name": "MovingObject", + "type": "objectList" + }, + { + "description": "Rectangle Movement (required)", + "name": "RectangleMovement", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Center object", + "name": "CenterObject", + "type": "objectList" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Move objects in a rectangular pattern.", + "fullName": "Rectangular movement", + "name": "RectangleMovement", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyOldX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyOldY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set the initial state according to the configuration." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyInitialPosition" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Top-right corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::TopRightDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyInitialPosition" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Bottom-right corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::BottomRightDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyInitialPosition" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Bottom-left corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::BottomLeftDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X() - Object.Behavior::DeltaX()" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y() - Object.Behavior::DeltaY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update the rectangle when the object is moved outside of the behavior." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.X() - Object.Behavior::PropertyOldX()" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyTop" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Y() - Object.Behavior::PropertyOldY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move the object on the rectangular path." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "MettreXY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyLeft() + Object.Behavior::DeltaX()", + "=", + "Object.Behavior::PropertyTop() + Object.Behavior::DeltaY()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Save the position to detect when the object is moved outside of the behavior." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyOldX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyOldY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Step on the path." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "mod(Object.Behavior::PropertyProgress() + TimeDelta() / Object.Behavior::LoopDuration(), 1)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "mod(Object.Behavior::PropertyProgress() - TimeDelta() / Object.Behavior::LoopDuration(), 1)" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Teleport the object to a corner of the movement rectangle.", + "fullName": "Teleport at a corner", + "functionType": "Action", + "name": "TeleportToCorner", + "sentence": "Set the position of _PARAM0_ at the _PARAM2_ of the rectangle loop", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareStrings" + }, + "parameters": [ + "GetArgumentAsString(\"Corner\")", + "=", + "\"Top-left corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareStrings" + }, + "parameters": [ + "GetArgumentAsString(\"Corner\")", + "=", + "\"Top-right corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::TopRightDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareStrings" + }, + "parameters": [ + "GetArgumentAsString(\"Corner\")", + "=", + "\"Bottom-right corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::BottomRightDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareStrings" + }, + "parameters": [ + "GetArgumentAsString(\"Corner\")", + "=", + "\"Bottom-left corner\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyProgress" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::BottomLeftDuration() / Object.Behavior::LoopDuration()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Corner", + "name": "Corner", + "supplementaryInformation": "[\"Top-left corner\",\"Top-right corner\",\"Bottom-left corner\",\"Bottom-right corner\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Return the perimeter of the movement rectangle.", + "fullName": "Perimeter", + "functionType": "Expression", + "group": "Rectangular movement shape", + "name": "Perimeter", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "2 * (abs(Object.Behavior::PropertyWidth()) + abs(Object.Behavior::PropertyHeight()))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the time the object takes to go through the whole rectangle (in seconds).", + "fullName": "Loop duration", + "functionType": "Expression", + "name": "LoopDuration", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "2 * (Object.Behavior::PropertyHorizontalEdgeDuration() + Object.Behavior::PropertyVerticalEdgeDuration())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the time the object takes to go through a horizontal edge (in seconds).", + "fullName": "Horizontal edge duration", + "functionType": "Expression", + "name": "HorizontalEdgeDuration", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHorizontalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the time the object takes to go through a vertical edge (in seconds).", + "fullName": "Vertical edge duration", + "functionType": "Expression", + "name": "VerticalEdgeDuration", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyVerticalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the rectangle width.", + "fullName": "Width", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Width", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyWidth()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the rectangle height.", + "fullName": "Height", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Height", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHeight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the left bound of the movement.", + "fullName": "Left bound", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Left", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyLeft()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the top bound of the movement.", + "fullName": "Top bound", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Top", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTop()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the right bound of the movement.", + "fullName": "Right bound", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Right", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyLeft() + Object.Behavior::PropertyWidth()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the bottom bound of the movement.", + "fullName": "Bottom bound", + "functionType": "Expression", + "group": "Rectangular movement/Shape", + "name": "Bottom", + "sentence": "Set initial Y of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTop() + Object.Behavior::PropertyHeight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the left bound of the rectangular movement.", + "fullName": "Left bound", + "functionType": "Action", + "group": "Rectangular movement shape", + "name": "SetLeft", + "sentence": "Change the movement left bound of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyWidth" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Behavior::PropertyLeft() - GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the top bound of the rectangular movement.", + "fullName": "Top bound", + "functionType": "Action", + "group": "Rectangular movement shape", + "name": "SetTop", + "sentence": "Change the movement top bound of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyHeight" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Behavior::PropertyTop() - GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the right bound of the rectangular movement.", + "fullName": "Right bound", + "functionType": "Action", + "group": "Rectangular movement shape", + "name": "SetRight", + "sentence": "Change the movement right bound of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyWidth" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\") - Object.Behavior::PropertyLeft()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the bottom bound of the rectangular movement.", + "fullName": "Bottom bound", + "functionType": "Action", + "group": "Rectangular movement shape", + "name": "SetBottom", + "sentence": "Change the movement bottom bound of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyHeight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\") - Object.Behavior::PropertyTop()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the time the object takes to go through a horizontal edge (in seconds).", + "fullName": "Horizontal edge duration", + "functionType": "Action", + "group": "Rectangular movement speed", + "name": "SetHorizontalEdgeDuration", + "sentence": "Change the time _PARAM0_ takes to go through a horizontal edge to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyHorizontalEdgeDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the time the object takes to go through a vertical edge (in seconds).", + "fullName": "Vertical edge duration", + "functionType": "Action", + "group": "Rectangular movement speed", + "name": "SetVerticalEdgeDuration", + "sentence": "Change the time _PARAM0_ takes to go through a vertical edge to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyVerticalEdgeDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the direction to clockwise or counter-clockwise.", + "fullName": "Clockwise", + "functionType": "Action", + "group": "Rectangular movement speed", + "name": "SetClockwise", + "sentence": "Use clockwise direction for _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Value\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Value\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Clockwise", + "name": "Value", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Change the easing function of the movement.", + "fullName": "Easing", + "functionType": "Action", + "group": "Rectangular movement speed", + "name": "SetEasing", + "sentence": "Change the easing of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyEasing" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + }, + { + "description": "Easing", + "name": "Easing", + "supplementaryInformation": "[\"linear\",\"easeInQuad\",\"easeOutQuad\",\"easeInOutQuad\",\"easeInCubic\",\"easeOutCubic\",\"easeInOutCubic\",\"easeInQuart\",\"easeOutQuart\",\"easeInOutQuart\",\"easeInQuint\",\"easeOutQuint\",\"easeInOutQuint\",\"easeInOutSine\",\"easeInExpo\",\"easeOutExpo\",\"easeInOutExpo\",\"easeInCirc\",\"easeOutCirc\",\"easeInOutCirc\",\"easeOutBounce\",\"easeInBack\",\"easeOutBack\",\"easeInOutBack\",\"elastic\",\"swingFromTo\",\"swingFrom\",\"swingTo\",\"bounce\",\"bouncePast\",\"easeFromTo\",\"easeFrom\",\"easeTo\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Toggle the direction to clockwise or counter-clockwise.", + "fullName": "Toggle direction", + "functionType": "Action", + "name": "ToogleClockwise", + "sentence": "Toogle the direction of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyToogleClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyToogleClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "=" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyToogleClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyToogleClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::SetPropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is moving clockwise.", + "fullName": "Is moving clockwise", + "functionType": "Condition", + "name": "IsMovingClockwise", + "sentence": "_PARAM0_ is moving clockwise", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is moving to the left.", + "fullName": "Is moving left", + "functionType": "Condition", + "name": "IsMovingLeft", + "sentence": "_PARAM0_ is moving to the left", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnTop" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnBottom" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is moving up.", + "fullName": "Is moving up", + "functionType": "Condition", + "name": "IsMovingUp", + "sentence": "_PARAM0_ is moving up", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnRight" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Object is moving to the right.", + "fullName": "Is moving right", + "functionType": "Condition", + "name": "IsMovingRight", + "sentence": "_PARAM0_ is moving to the right", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnTop" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnBottom" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is moving down.", + "fullName": "Is moving down", + "functionType": "Condition", + "name": "IsMovingDown", + "sentence": "_PARAM0_ is moving down", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnRight" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "RectangleMovement::RectangleMovement::PropertyClockwise" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "RectangleMovement::RectangleMovement::IsOnLeft" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Object is on the left side of the rectangle.", + "fullName": "Is on left", + "functionType": "Condition", + "name": "IsOnLeft", + "sentence": "_PARAM0_ is on the left side", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::BottomLeftDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Object is on the top side of the rectangle.", + "fullName": "Is on top", + "functionType": "Condition", + "name": "IsOnTop", + "sentence": "_PARAM0_ is on the top side", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<=", + "Object.Behavior::TopRightDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Object is on the right side of the rectangle.", + "fullName": "Is on right", + "functionType": "Condition", + "name": "IsOnRight", + "sentence": "_PARAM0_ is on the right side", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::TopRightDuration()" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<=", + "Object.Behavior::BottomRightDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Object is on the bottom side of the rectangle.", + "fullName": "Is on bottom", + "functionType": "Condition", + "name": "IsOnBottom", + "sentence": "_PARAM0_ is on the bottom side", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::BottomRightDuration()" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<=", + "Object.Behavior::BottomLeftDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the duration between the top-left vertex and the top-right one.", + "fullName": "Duration to top right", + "functionType": "Expression", + "name": "TopRightDuration", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHorizontalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the duration between the top-left vertex and the bottom-right one.", + "fullName": "Duration to bottom right", + "functionType": "Expression", + "name": "BottomRightDuration", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHorizontalEdgeDuration() + Object.Behavior::PropertyVerticalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the duration between the top-left vertex and the bottom-left one.", + "fullName": "Duration to bottom left", + "functionType": "Expression", + "name": "BottomLeftDuration", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "2 * Object.Behavior::PropertyHorizontalEdgeDuration() + Object.Behavior::PropertyVerticalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the ratio between the covered distance from the last vertex and the edge length (between 0 and 1).", + "fullName": "Progress on edge", + "functionType": "Expression", + "name": "EdgeProgress", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::HalfCurrentTime() / Object.Behavior::PropertyHorizontalEdgeDuration()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::HalfCurrentTime()", + ">=", + "abs(Object.Behavior::PropertyHorizontalEdgeDuration())" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "(Object.Behavior::HalfCurrentTime() - Object.Behavior::PropertyHorizontalEdgeDuration()) / Object.Behavior::PropertyVerticalEdgeDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the X position of the current edge origin.", + "fullName": "Edge origin X", + "functionType": "Expression", + "name": "EdgeOriginX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::TopRightDuration()" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<", + "Object.Behavior::BottomLeftDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyWidth()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the Y position of the current edge origin.", + "fullName": "Edge origin Y", + "functionType": "Expression", + "name": "EdgeOriginY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::BottomRightDuration()" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<", + "Object.Behavior::Perimeter()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHeight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the X position of the current edge target.", + "fullName": "Edge target X", + "functionType": "Expression", + "name": "EdgeTargetY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + ">=", + "Object.Behavior::TopRightDuration()" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<", + "Object.Behavior::BottomLeftDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHeight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the Y position of the current edge target.", + "fullName": "Edge target Y", + "functionType": "Expression", + "name": "EdgeTargetX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CurrentTime()", + "<", + "Object.Behavior::BottomRightDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyWidth()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the time from the top-left vertex.", + "fullName": "Current time", + "functionType": "Expression", + "name": "CurrentTime", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyProgress() * Object.Behavior::LoopDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the covered length from the top-left vertex or the bottom-right one.", + "fullName": "Half Current length", + "functionType": "Expression", + "name": "HalfCurrentTime", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object. Behavior::LoopDuration() * mod(Object.Behavior::PropertyProgress(), 0.5)" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on the X axis from the top-left vertex.", + "fullName": "Delta X", + "functionType": "Expression", + "name": "DeltaX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Tween::Ease(Object.Behavior::PropertyEasing(), Object.Behavior::EdgeOriginX(), Object.Behavior::EdgeTargetX(), Object.Behavior::EdgeProgress())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on the Y axis from the top-left vertex.", + "fullName": "Delta Y", + "functionType": "Expression", + "name": "DeltaY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Tween::Ease(Object.Behavior::PropertyEasing(), Object.Behavior::EdgeOriginY(), Object.Behavior::EdgeTargetY(), Object.Behavior::EdgeProgress())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "RectangleMovement::RectangleMovement", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "100", + "type": "Number", + "unit": "Pixel", + "label": "Width", + "description": "", + "group": "Dimension", + "extraInformation": [], + "hidden": false, + "name": "Width" + }, + { + "value": "100", + "type": "Number", + "unit": "Pixel", + "label": "Height", + "description": "", + "group": "Dimension", + "extraInformation": [], + "hidden": false, + "name": "Height" + }, + { + "value": "true", + "type": "Boolean", + "label": "Clockwise", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "Clockwise" + }, + { + "value": "4", + "type": "Number", + "unit": "Second", + "label": "Horizontal edge duration", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "HorizontalEdgeDuration" + }, + { + "value": "1", + "type": "Number", + "unit": "Second", + "label": "Vertical edge duration", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "VerticalEdgeDuration" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Left" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Top" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Progress" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "OldY" + }, + { + "value": "easeInOutSine", + "type": "Choice", + "label": "Easing", + "description": "", + "group": "Speed", + "extraInformation": [ + "linear", + "easeInQuad", + "easeOutQuad", + "easeInOutQuad", + "easeInCubic", + "easeOutCubic", + "easeInOutCubic", + "easeInQuart", + "easeOutQuart", + "easeInOutQuart", + "easeInQuint", + "easeOutQuint", + "easeInOutQuint", + "easeInOutSine", + "easeInExpo", + "easeOutExpo", + "easeInOutExpo", + "easeInCirc", + "easeOutCirc", + "easeInOutCirc", + "easeOutBounce", + "easeInBack", + "easeOutBack", + "easeInOutBack", + "elastic", + "swingFromTo", + "swingFrom", + "swingTo", + "bounce", + "bouncePast", + "easeFromTo", + "easeFrom", + "easeTo" + ], + "hidden": false, + "name": "Easing" + }, + { + "value": "Top-left corner", + "type": "Choice", + "label": "Initial position", + "description": "", + "group": "", + "extraInformation": [ + "Top-left corner", + "Top-right corner", + "Bottom-right corner", + "Bottom-left corner" + ], + "hidden": false, + "name": "InitialPosition" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ToogleClockwise" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + } + ], + "externalLayouts": [], + "externalSourceFiles": [] +} \ No newline at end of file