From edffcfb6e37886035aa696e7431f587082eb96d7 Mon Sep 17 00:00:00 2001 From: John Benediktsson Date: Mon, 1 Aug 2022 08:14:26 -0700 Subject: [PATCH] sokoban: removing in favor of newer gamelib.demos.sokoban --- extra/sokoban/README.txt | 7 - extra/sokoban/authors.txt | 1 - extra/sokoban/board/board-tests.factor | 23 --- extra/sokoban/board/board.factor | 39 ----- extra/sokoban/deploy.factor | 13 -- extra/sokoban/game/game-tests.factor | 15 -- extra/sokoban/game/game.factor | 119 ------------- extra/sokoban/gl/gl.factor | 66 ------- extra/sokoban/layout/layout.factor | 171 ------------------- extra/sokoban/piece/piece.factor | 75 -------- extra/sokoban/resources/CharB.png | Bin 1435 -> 0 bytes extra/sokoban/resources/CharF.png | Bin 1668 -> 0 bytes extra/sokoban/resources/CharL.png | Bin 1487 -> 0 bytes extra/sokoban/resources/CharR.png | Bin 1474 -> 0 bytes extra/sokoban/resources/CharWalkB.png | Bin 1492 -> 0 bytes extra/sokoban/resources/CharWalkF.png | Bin 1747 -> 0 bytes extra/sokoban/resources/CharWalkL.png | Bin 1544 -> 0 bytes extra/sokoban/resources/CharWalkR.png | Bin 1564 -> 0 bytes extra/sokoban/resources/CrateDark_Yellow.png | Bin 1140 -> 0 bytes extra/sokoban/resources/Crate_Yellow.png | Bin 1162 -> 0 bytes extra/sokoban/resources/once.wav | Bin 44144 -> 0 bytes extra/sokoban/sokoban.factor | 97 ----------- extra/sokoban/sound/sound.factor | 18 -- extra/sokoban/summary.txt | 1 - extra/sokoban/tags.txt | 3 - 25 files changed, 648 deletions(-) delete mode 100644 extra/sokoban/README.txt delete mode 100644 extra/sokoban/authors.txt delete mode 100644 extra/sokoban/board/board-tests.factor delete mode 100644 extra/sokoban/board/board.factor delete mode 100644 extra/sokoban/deploy.factor delete mode 100644 extra/sokoban/game/game-tests.factor delete mode 100644 extra/sokoban/game/game.factor delete mode 100644 extra/sokoban/gl/gl.factor delete mode 100644 extra/sokoban/layout/layout.factor delete mode 100644 extra/sokoban/piece/piece.factor delete mode 100644 extra/sokoban/resources/CharB.png delete mode 100644 extra/sokoban/resources/CharF.png delete mode 100644 extra/sokoban/resources/CharL.png delete mode 100644 extra/sokoban/resources/CharR.png delete mode 100644 extra/sokoban/resources/CharWalkB.png delete mode 100644 extra/sokoban/resources/CharWalkF.png delete mode 100644 extra/sokoban/resources/CharWalkL.png delete mode 100644 extra/sokoban/resources/CharWalkR.png delete mode 100644 extra/sokoban/resources/CrateDark_Yellow.png delete mode 100644 extra/sokoban/resources/Crate_Yellow.png delete mode 100644 extra/sokoban/resources/once.wav delete mode 100644 extra/sokoban/sokoban.factor delete mode 100644 extra/sokoban/sound/sound.factor delete mode 100644 extra/sokoban/summary.txt delete mode 100644 extra/sokoban/tags.txt diff --git a/extra/sokoban/README.txt b/extra/sokoban/README.txt deleted file mode 100644 index a3bdf792ef..0000000000 --- a/extra/sokoban/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -This is a simple sokoban game. To play, open factor (in GUI mode), and run: - -"sokoban" run - -This should open a new window with a running sokoban game. The commands are: - -left,right,up,down arrows -- moves the player in the given direction diff --git a/extra/sokoban/authors.txt b/extra/sokoban/authors.txt deleted file mode 100644 index 36ce64f6f0..0000000000 --- a/extra/sokoban/authors.txt +++ /dev/null @@ -1 +0,0 @@ -Factor Clinic Team 2021-2022 diff --git a/extra/sokoban/board/board-tests.factor b/extra/sokoban/board/board-tests.factor deleted file mode 100644 index 2d25adeb71..0000000000 --- a/extra/sokoban/board/board-tests.factor +++ /dev/null @@ -1,23 +0,0 @@ -USING: accessors arrays colors kernel sokoban.board sokoban.piece tools.test ; - -{ { { f f } { f f } { f f } } } [ 2 3 make-rows ] unit-test -{ { { f f } { f f } { f f } } } [ 2 3 rows>> ] unit-test -{ 1 { f f } } [ 2 3 { 1 1 } board@block ] unit-test -{ f } [ 2 3 { 1 1 } block ] unit-test -[ 2 3 { 2 3 } block ] must-fail -{ COLOR: red } [ 2 3 dup { 1 1 } COLOR: red set-block { 1 1 } block ] unit-test -{ t } [ 2 3 { 1 1 } block-free? ] unit-test -{ f } [ 2 3 dup { 1 1 } COLOR: red set-block { 1 1 } block-free? ] unit-test -{ t } [ 2 3 dup { 1 1 } COLOR: red set-block { 1 2 } block-free? ] unit-test -{ t } [ 2 3 dup { 1 1 } COLOR: red set-block { 0 1 } block-free? ] unit-test -{ t } [ 2 3 { 0 0 } block-in-bounds? ] unit-test -{ f } [ 2 3 { -1 0 } block-in-bounds? ] unit-test -{ t } [ 2 3 { 1 2 } block-in-bounds? ] unit-test -{ f } [ 2 3 { 2 2 } block-in-bounds? ] unit-test -{ t } [ 2 3 { 1 1 } location-valid? ] unit-test -{ f } [ 2 3 dup { 1 1 } COLOR: red set-block { 1 1 } location-valid? ] unit-test -! { t } [ 10 10 10 piece-valid? ] unit-test -! { f } [ 2 3 10 { 1 2 } >>location piece-valid? ] unit-test -! { { { f } { f } } } [ 1 1 add-row rows>> ] unit-test -! { { { f } } } [ 1 2 dup { 0 1 } COLOR: red set-block remove-full-rows rows>> ] unit-test -! { { { f } { f } } } [ 1 2 dup { 0 1 } COLOR: red set-block dup check-rows drop rows>> ] unit-test diff --git a/extra/sokoban/board/board.factor b/extra/sokoban/board/board.factor deleted file mode 100644 index 800bf8416e..0000000000 --- a/extra/sokoban/board/board.factor +++ /dev/null @@ -1,39 +0,0 @@ -! Copyright (C) 2006, 2007, 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays combinators.short-circuit fry kernel -math sequences sokoban.piece sokoban.layout ; -IN: sokoban.board - -TUPLE: board - { width integer } - { height integer } - { rows array } ; - -: make-rows ( width height -- rows ) - swap '[ _ f ] replicate ; - -: ( width height -- board ) - 2dup make-rows board boa ; - -! A block is simply an array of form { x y } where { 0 0 } is -! the top-left of the sokoban board, and { 9 19 } is the bottom -! right on a 10x20 board. - -: board@block ( board block -- n row ) - [ second swap rows>> nth ] keep first swap ; - -: set-block ( board block color -- ) -rot board@block set-nth ; - -: block ( board block -- color ) board@block nth ; - -: block-free? ( board block -- ? ) block not ; - -: block-in-bounds? ( board block -- ? ) - [ first swap width>> bounds-check? ] - [ second swap height>> bounds-check? ] 2bi and ; - -: location-valid? ( board block -- ? ) - { [ block-in-bounds? ] [ block-free? ] } 2&& ; - -: piece-valid? ( board piece -- ? ) - piece-blocks [ location-valid? ] with all? ; diff --git a/extra/sokoban/deploy.factor b/extra/sokoban/deploy.factor deleted file mode 100644 index ea8750f6d1..0000000000 --- a/extra/sokoban/deploy.factor +++ /dev/null @@ -1,13 +0,0 @@ -USING: tools.deploy.config ; -H{ - { deploy-ui? t } - { deploy-threads? t } - { deploy-word-props? f } - { deploy-reflection 1 } - { "stop-after-last-window?" t } - { deploy-io 3 } - { deploy-math? t } - { deploy-word-defs? f } - { deploy-c-types? f } - { deploy-name "sokoban" } -} diff --git a/extra/sokoban/game/game-tests.factor b/extra/sokoban/game/game-tests.factor deleted file mode 100644 index 07cd3c20b2..0000000000 --- a/extra/sokoban/game/game-tests.factor +++ /dev/null @@ -1,15 +0,0 @@ -USING: accessors kernel sokoban.game sokoban.board sokoban.piece tools.test -sequences ; - -! { t } [ [ current-piece ] [ next-piece ] bi and t f ? ] unit-test -! { t } [ { 1 1 } can-move? ] unit-test -{ t } [ { 1 1 } sokoban-move ] unit-test -! { 1 } [ dup { 1 1 } sokoban-move drop current-piece location>> second ] unit-test -{ 0 } [ level>> ] unit-test -! { 1 } [ 9 >>rows level>> ] unit-test -! { 2 } [ 10 >>rows level>> ] unit-test -! { 0 } [ 3 0 rows-score ] unit-test -! { 80 } [ 1 1 rows-score ] unit-test -! { 4800 } [ 3 4 rows-score ] unit-test -! { 1 } [ dup 3 score-rows dup 3 score-rows dup 3 score-rows level ] unit-test -! { 2 } [ dup 4 score-rows dup 4 score-rows dup 2 score-rows level ] unit-test diff --git a/extra/sokoban/game/game.factor b/extra/sokoban/game/game.factor deleted file mode 100644 index fa4cfd1ab2..0000000000 --- a/extra/sokoban/game/game.factor +++ /dev/null @@ -1,119 +0,0 @@ -! Copyright (C) 2006, 2007, 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. - -USING: accessors combinators kernel lists math math.functions math.vectors -sequences system sokoban.board sokoban.piece sokoban.layout sokoban.sound colors -namespaces locals ; - -IN: sokoban.game - -TUPLE: sokoban - { board } - { player } - { boxes } - { goals } - { engine } - { last-update integer initial: 0 } - { level integer initial: 0 } - { paused? initial: f } - { running? initial: t } ; - -: add-wall-block ( sokoban block -- ) - over [ board>> ] 2dip swap level>> rotate-piece layout>> color>> set-block ; - -: add-walls ( sokoban -- ) - dup swap level>> rotate-piece wall-blocks [ add-wall-block ] with each ; - -:: ( lev w h -- sokoban ) - ! make components - w h :> board - lev :> player - lev :> goals - - ! put components into sokoban instance - sokoban new :> soko - soko player >>player - lev >>level - board >>board - goals >>goals - goals lev >>boxes - soko add-walls ; ! draw walls - - -: ( -- sokoban ) - ! Level 0 sokoban - 0 8 9 ; - -: toggle-pause ( sokoban -- ) - [ not ] change-paused? drop ; - -: can-player-move? ( sokoban move -- ? ) - [ drop board>> ] [ [ player>> clone ] dip move-piece ] 2bi piece-valid? ; - -:: get-adj-box ( soko piece mov -- box ) - ! If the input piece (either a player or another box) has a box at its move location, - ! return the box at the move location. Otherwise, return false - piece location>> :> player_loc - player_loc mov v+ :> next_loc - soko boxes>> :> box_list - box_list [ location>> next_loc = ] find swap drop ; - -:: can-box-move? ( soko box mov -- ? ) - soko box mov get-adj-box :> box2move ! Checks if input box has a box at its move location - box2move - [ ! If there is another box at the move location, the current box is unable to move - f - ] - [ ! Otherwise, we check if there is a wall blocking the box - soko board>> box clone mov move-piece piece-valid? - ] if ; - -:: sokoban-move ( soko mov -- ? ) - ! Collision logic -- checks if player can move and moves the player accordingly - soko mov can-player-move? - [ ! Player can move - soko dup player>> mov get-adj-box :> box2move - box2move - [ ! Next location of player is a box - soko box2move mov can-box-move? - [ ! Next location of player is a box and box is able to move - soko goals>> box2move location>> mov is-goal? - [ ! Next location of box is a goal point - soko player>> mov move-piece drop - box2move mov move-piece - soko engine>> play-beep - "vocab:sokoban/resources/CrateDark_Yellow.png" >>path - layout>> COLOR: blue >>color drop t ! change color once box is on goal - ] - [ ! Next location of box is a free space - soko player>> mov move-piece drop - box2move mov move-piece - layout>> COLOR: orange >>color drop t - ] if - ] - [ ! Next location of player is a box but box cannot move - f - ] if - ] - [ ! Next location of player is a free space, move the player onto the free space - soko player>> mov move-piece drop t - ] if - ] - [ ! Player cannot move - f - ] if ; - -: move-left ( sokoban -- ) dup player>> "vocab:sokoban/resources/CharL.png" >>path drop { -1 0 } sokoban-move drop ; - -: move-right ( sokoban -- ) dup player>> "vocab:sokoban/resources/CharR.png" >>path drop { 1 0 } sokoban-move drop ; - -: move-down ( sokoban -- ) dup player>> "vocab:sokoban/resources/CharF.png" >>path drop { 0 1 } sokoban-move drop ; - -: move-up ( sokoban -- ) dup player>> "vocab:sokoban/resources/CharB.png" >>path drop { 0 -1 } sokoban-move drop ; - -: update-level? ( sokoban -- ? ) - ! Get color color of each box - boxes>> [ layout>> ] map [ color>> ] map - ! All boxes are on correct spots if there are no orange boxes left and level should be updated - [ COLOR: orange ] first swap member? not ; - diff --git a/extra/sokoban/gl/gl.factor b/extra/sokoban/gl/gl.factor deleted file mode 100644 index b8fe358b9c..0000000000 --- a/extra/sokoban/gl/gl.factor +++ /dev/null @@ -1,66 +0,0 @@ -! Copyright (C) 2006, 2007, 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays colors combinators math.vectors -kernel math opengl opengl.gl opengl.textures sequences sokoban.game sokoban.piece images.loader -; - -IN: sokoban.gl - -! OpenGL rendering for sokoban ; - -: draw-block ( block -- ) - { 1 1 } gl-fill-rect ; - -: draw-sprite ( block path -- ) - load-image swap { 1 1 } swap draw-scaled-texture ; - -:: draw-piece-blocks ( piece -- ) - piece piece-blocks [ piece path>> draw-sprite ] each ; - -: draw-piece ( piece -- ) - dup layout>> color>> gl-color draw-piece-blocks ; - -: draw-goal ( block -- ) - { 0.38 0.38 } v+ { 0.24 0.24 } gl-fill-rect ; - -: draw-goal-blocks ( piece -- ) - ! implement goals the same way we do as walls - wall-blocks [ draw-goal ] each ; - -: draw-goal-piece ( piece -- ) - dup layout>> color>> gl-color draw-goal-blocks ; - -! TODO: move implementation specific stuff into sokoban-board -: (draw-row) ( x y row -- ) - overd nth [ gl-color 2array draw-block ] [ 2drop ] if* ; - -: draw-row ( y row -- ) - [ length swap ] keep [ (draw-row) ] 2curry each ; - -: draw-board ( board -- ) - rows>> [ swap draw-row ] each-index ; - -: scale-board ( width height board -- ) - [ width>> ] [ height>> ] bi swapd [ / ] dup 2bi* 1 glScalef ; - -: set-background-color ( sokoban -- ) - dup running?>> [ - paused?>> COLOR: light-gray COLOR: white ? - ] [ drop COLOR: black ] if gl-color ; - -: draw-background ( board -- ) - [ 0 0 ] dip [ width>> ] [ height>> ] bi glRectf ; - -: draw-sokoban ( width height sokoban -- ) - ! width and height are in pixels - [ - { - [ board>> scale-board ] - [ set-background-color ] - [ board>> draw-background ] - [ board>> draw-board ] - [ player>> draw-piece ] - [ goals>> draw-goal-piece ] - [ boxes>> [ draw-piece ] each ] - } cleave - ] do-matrix ; diff --git a/extra/sokoban/layout/layout.factor b/extra/sokoban/layout/layout.factor deleted file mode 100644 index 7a5517d1e9..0000000000 --- a/extra/sokoban/layout/layout.factor +++ /dev/null @@ -1,171 +0,0 @@ -! Copyright (C) 2006, 2007, 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: kernel arrays namespaces sequences math math.order -math.vectors colors random ; -IN: sokoban.layout - -TUPLE: layout states color ; - -C: layout - -SYMBOL: component - -{ - [ ! walls on each level - { - { - { 2 0 } { 3 0 } { 4 0 } { 5 0 } { 6 0 } - { 0 1 } { 1 1 } { 2 1 } { 6 1 } - { 0 2 } { 6 2 } - { 0 3 } { 1 3 } { 2 3 } { 6 3 } - { 0 4 } { 2 4 } { 3 4 } { 6 4 } - { 0 5 } { 2 5 } { 6 5 } { 7 5 } - { 0 6 } { 7 6 } - { 0 7 } { 7 7 } - { 0 8 } { 1 8 } { 2 8 } { 3 8 } { 4 8 } { 5 8 } { 6 8 } { 7 8 } - } - { ! new level (access it by rotating the level piece) - { 4 0 } { 5 0 } { 6 0 } { 7 0 } { 8 0 } - { 4 1 } { 8 1 } - { 4 2 } { 8 2 } - { 2 3 } { 3 3 } { 4 3 } { 8 3 } { 9 3 } { 10 3 } - { 2 4 } { 10 4 } - { 0 5 } { 1 5 } { 2 5 } { 4 5 } { 6 5 } { 7 5 } { 8 5 } { 10 5 } { 16 5 } { 17 5 } { 18 5 } { 19 5 } { 20 5 } { 21 5 } - { 0 6 } { 4 6 } { 6 6 } { 7 6 } { 8 6 } { 10 6 } { 11 6 } { 12 6 } { 13 6 } { 14 6 } { 15 6 } { 16 6 } { 21 6 } - { 0 7 } { 21 7 } - { 0 8 } { 1 8 } { 2 8 } { 3 8 } { 4 8 } { 6 8 } { 7 8 } { 8 8 } { 10 8 } { 12 8 } { 13 8 } { 14 8 } { 15 8 } { 16 8 } { 21 8 } - { 4 9 } { 10 9 } { 11 9 } { 12 9 } { 16 9 } { 17 9 } { 18 9 } { 19 9 } { 20 9 } { 21 9 } - { 4 10 } { 5 10 } { 6 10 } { 7 10 } { 8 10 } { 9 10 } { 10 10 } - - } - } COLOR: gray - ] - [ ! player position on each level - { - { - { 2 2 } - } - { - { 11 8 } - } - } COLOR: green - ] - [ - { - { - { 1 2 } { 5 3 } { 1 4 } { 4 5 } { 3 6 } { 6 6 } { 4 7 } - } - { - { 19 6 } { 20 6 } - { 19 7 } { 20 7 } - { 19 8 } { 20 8 } - } - } COLOR: pink - ] -} [ first2 ] map component set-global - -SYMBOL: boxes -{ - { ! first box on each level - { - { ! level 0 - { 3 2 } - } - - { ! level 1 - { 5 2 } - } - } COLOR: orange - } - - { ! second box on each level - { - { ! level 0 - { 4 3 } - } - - { ! level 1 - { 7 3 } - } - } COLOR: orange - } - - { ! third box on each level - { - { ! level 0 - { 4 4 } - } - { ! level 1 - { 5 4 } - } - } COLOR: orange - } - - { ! fourth box on each level - { - { ! level 0 - { 4 6 } - } - { ! level 1 - { 8 4 } - } - } COLOR: orange - } - - { ! fifth box on each level - { - { ! level 0 - { 3 6 } - } - { ! level 1 - { 5 7 } - } - } COLOR: orange - } - - { ! sixth box on each level - { - { ! level 0 - { 5 6 } - } - { ! level 1 - { 2 7 } - } - } COLOR: orange - } - - { ! seventh box on each level - { - { ! level 0 - { 1 6 } - } - } COLOR: orange - } - - ! etc -} [ first2 ] map boxes set-global - - -SYMBOL: num-boxes -{ - ! number of boxes -1 of each level - 6 - 5 -} num-boxes set-global - -: get-board ( -- layout ) - component get first ; - -: get-player ( -- layout ) - component get second ; - -: get-box ( n -- layout ) - boxes get nth ; - ! TODO add an n argument and get (n + 1)th - -: get-goal ( -- layout ) - component get third ; - -: get-num-boxes ( n -- m ) - ! outputs how many boxes are on each level, allows for different numbers of boxes per level - num-boxes get nth ; diff --git a/extra/sokoban/piece/piece.factor b/extra/sokoban/piece/piece.factor deleted file mode 100644 index 01aca87e0b..0000000000 --- a/extra/sokoban/piece/piece.factor +++ /dev/null @@ -1,75 +0,0 @@ -! Copyright (C) 2006, 2007, 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays kernel math math.vectors sequences -sokoban.layout lists.lazy namespaces colors -ranges random ; -IN: sokoban.piece - -! The level_num is an index into the layout's states array, -! and the position is added to the layout's blocks to give -! them their location on the sokoban board. If the location is f -! then the piece is not yet on the board. - -TUPLE: piece - { layout layout } - { level_num integer initial: 0 } - { location array initial: { 0 0 } } - { path } ; - -: ( layout -- piece ) - piece new swap >>layout ; - -: (piece-blocks) ( piece -- blocks ) - ! rotates the piece - [ level_num>> ] [ layout>> states>> ] bi nth ; - -: wall-blocks ( piece -- blocks ) - [ (piece-blocks) ] [ location>> ] bi [ v+ ] curry map ; - -: piece-blocks ( piece -- blocks ) - location>> { } 1sequence ; ! literally just returns the location in a sequence - -: set-location ( piece level -- piece ) - ! sets the location of piece to where they are defined in layout - over layout>> states>> nth first >>location ; - -: is-goal? ( goal-piece location move -- ? ) - ! check if next move is a goal or not - v+ swap [ level_num>> ] [ layout>> ] bi states>> nth member? ; - -: ( -- piece ) - get-board ; - -: ( level -- piece ) - get-player swap set-location "vocab:sokoban/resources/CharR.png" >>path ; - - -:: ( box-number goal-piece level -- piece ) - box-number get-box level set-location "vocab:sokoban/resources/Crate_Yellow.png" >>path dup [ layout>> ] [ location>> ] bi - goal-piece swap { 0 0 } is-goal? - [ - COLOR: blue - ] - [ - COLOR: orange - ] if - >>color drop ; - -:: ( goal-piece level -- seq ) - ! get list of boxes on corresponding level - level get-num-boxes [0..b] [ goal-piece level ] map ; - -: (rotate-piece) ( level_num inc n-states -- level_num' ) - [ + ] dip rem ; - -: rotate-piece ( piece inc -- piece ) - over layout>> states>> length - [ (rotate-piece) ] 2curry change-level_num ; - -: ( level -- piece ) - ! rotate goal according to level - get-goal swap rotate-piece ; - - -: move-piece ( piece move -- piece ) - [ v+ ] curry change-location ; diff --git a/extra/sokoban/resources/CharB.png b/extra/sokoban/resources/CharB.png deleted file mode 100644 index 7f94ffa2953e5b01c2019a10a6ee94c641bf98e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1435 zcmV;M1!Ve(P)g@tE8#B@H;t|94S2P%#jUWR{dv z2}rSibCp9uM&p^Xi^|!GpqPOeZvk4_qYriGaV{9VW(`OiDm~rZs}Gg5bLSzX(xDUr zg7knOgwPqflbgkowHVS+B0z$bT`RFe zw=Bu)#GzK)(op%sTDlbI^-xCA^j5;9K|Y_{;!qGgE0gRjo#dg+ie`mHR33`g8C2LY zScej=PZiWFc_>tAD^L>k3jLf!yRyR?Q2rcjk}CfiJOM!*b zP&j5lh9-X7LMIWzlAg-+{Hr8%f*~yHr%b(7Y3Kw(Sk`&sgRHmQWeSIIxBL^0Zd+`% zU>Y9KJIWqPO`rYBz>FTvt*Ype9(g4El)Uv0Dws*^N>vqTE8$Ta^T&zor|!sC?$AUi zIX62>qdyK&|99`wuThUQ#NRhxpi7a%bYbiyJzN~2_2d+#6O&#`Z(Ur2*J6%SleFuj z?`h}z=S%cd_b|O0@N@OzsZY!1L5I&=q~1$o5dmYpexZ2uuCPu1UfvZ%1{Ic#M zqOu?Rmg-N0sBtj5X_MWw7)|#%o5LRtx&~%a#ZV=HpUsh@cRUXXFY<&j4gOJb_D$*9 za`aD|ztwa4LlNi6vBKSKw;DhHnHqY+#$a{Fe{ciH`N>30fK*{ktgQ>>=n45Sz|}up zTPWrPtgWBi{*hQ7isejAq1X<`+WPr~&>^4LPOClCX!?H#g?0H*Y)8~K(Z|i9TmwJV z45;z+HB#3#Nc3;SCu3>+ z>wm=QU?Ac%tm+s5sE7Bi>w3!!3g64dFmLGr;l{BRw6VHi+%c$wp!4%_At-16%%cOA z9n{+E@SfHVZWvw?g33LJM~cDTxm;>YFFdZIx&}b)b%1K2W^X(K%KaHn^M9MUzi=S4 z8c(Scva9i6(_l1N@C1^V6B;Bx4;nfejs=TvJo6xC-i59u=526i!KK|H8yYgzsQtqW zTrU(igJ|js*G?~_9fMJ?dh@W4zZLyT+TshOtQN_=M~72QeKYQ={-oi=JJLtZA77*=2d0w{zC-(cU(ic$ zdZ~C0Y*ZVHc2M+A3T>HzwD?7mH+?%Ep$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_e paCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1mezwwC|^ diff --git a/extra/sokoban/resources/CharF.png b/extra/sokoban/resources/CharF.png deleted file mode 100644 index 0315373306c49a71ee9559b3f8e44fb1f539790c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1668 zcmV-~27CF5P)VnQ}1wzUr^lJKHQD>23ggMGnNL|7vr&=yN2 zM8IJEAkuc*ZcE!O-G0mz0qqAY%a+nou!Inek#sB4G)UXy{HL8^cjw;OJIm6z$^W4{ z=brPs=bm$BcDIZ@#A_PRc*(S$%yc)1PKQzYX9B_dNtl~O>E2nfQ_O8T+wNPX_e0-b-{9tuY*=?fh$ z&XQgG%Z>v>;T6(Q5E8;IZYNG`J5RC$obwzi}@PNwq=VYoW* z8Pka%bOe;B^O7ibOTpt_SukxA3$w8kOu;Y>kY{R$Os$!GoaN`uMHGZjGfpy3jXvM zovcWss**+Yk&;$9uKVS(2@t}5Z z{m^0;y#e?X!QE<^gA!$Da^RTh=-d4sX(#~LK|xbjTex7Cy=;^Vb-gK5Uli>`1a+b1 zJ1Hp925z>!XaO5Mu01Ub)i7W5o8x_3EsGx&6i$N+6|Q1gS87?rc+;q(`GA6=frh-S z+`K9GA7N=%yex+Yc-i7*3BKN0rxXsDs-^EQQK8_LI7F8*E=T^f^Wo-2Flo8m6fsA@5?Ofpx3`SMR!6i zDFK6z;l4HV7>u86!+zK_Dt#EKQ0Kg304Y$(dV1O%JGwkp;0Jk@)OV?fpt)zr;_Zrbp}gLSSwele7%T6ria zBWnnFv|XjMz1=YabTrJoK_#RADO9U7D82jU47OGKsl?Z+YuWC4%GlYM5-6k4U#Vy? z{Tnf~Lih0Jl*bz^IMx(XtS15ieI%p;3c@gk&*&HcI&QUzql zxGR{C#UpBY;^%YC2+z+m*HqtFe|uU+X=i21pvpReyXv$@ZOu1gNCAmnuF}r(6(1j^ z+;!_IKR@5p%LSWh@xIoWz^gyl6=Q=nSc}cE;+oX`e4Cq_o23PaLPDe5{MQ&qnWMy)w27m4V O0000?BSA diff --git a/extra/sokoban/resources/CharL.png b/extra/sokoban/resources/CharL.png deleted file mode 100644 index cbf68570e66c6d5db89c98b6555d882d0181de38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1487 zcmV;=1u*)FP)}ol4W23tr5B~1mlGOquT-Q z7*{J`TKSCm4t^KGGXjm1;AGL!U16Y~0id!0et!gDgd~^$F%~=;$O|v}^NP|27^Mpw ztb1emD}YMiB(!{clYOqA7<7fi)w2#FWMCUJ(I!ohoFc;{v^YfcaW*pg?4CHJNf$uA zqPIy{Gpx`_{UQ0V3)hMI1jF*eLQ+|2gN*IjA>vhA8?EVfQmmz6QkHVaA@pcjl{v6*Uk+DJw=%;nd?$pW_vBp3-K(QEj>ms$YnXQvbi+CCm zD^_3cwv*;WptG)r*`p5po7V&~wgrZWIUfFYVi$wn^JHfv!xgyd5bjkb)O^qfH`gAL z3;(JNr!SBqF0mGFkaYoyk~{!{ZN#!(Ad}WqTm_yG>mD>#N13dP3>&C*56T{)vx8Qc zY=QY(FKz(PKd!-#O;#u^Erq(HdC>K34oo>WuWwMk_P@RxVB$E_3%rmvQ03jzjMpLs zio(xWOgdH0>!vkhaq&GoZ~W^`+4np93eZuBs4#wwyR756Wq#lWB4eX=_RpUF>GOW}Fbg_@L;rB2Z3K z=Th3ks;<$IXH*4Ck&==UyYBCu!Xr-e zed-E480&%P?4TylLhhwJry?}VAZH01#VMa>5~Au{b%1=-$l9-esj3wZp< zSuj|>qjZB@2)c8*N&Xw}jlrV+rMndYV+0n0eGt6iVgWg2ecTG!4Si+0fc`zcQt-J6 z(M>)q=P)h;VeSR`VDMTmEC0=2b}`)dUafD9gC6|>jP*TWY#az_hBVc7=DzWh&@pr{ z5iF{=-w8WvFG0@daUD3*!G3n?mkR?2B)Yc||+-e($L83IfiUV+ip|gLE3A26i?g0FA=PC<|&PjoyvOcoImJ?0^AYZEY zDu!J=*v_xLaJJtE_a}wG)U7^QNLIBjNk~oM#}!Hqiooxj_kyj<$7h2K~(GORt;a z<|LWKy#S}(XJq!~u{IsMd}c5#$Vy!0!(vZ>otLDW^*w3$f4xFj>;rJWqU4;!L{00j zAB>IeW}Gay?lL_0{-;p++Fq!xu1=`u57t2bhhK?KpaDv^>qoMu;DZLs%lqDv1QZJw zwC&4oz(yxyKX@rGFVAHr4=aV_i6WVNDl03kDj-=ge_OO6Kr1RL$}$~#Dpkm;swxLr zi>J7_*nkcxk(PP>2ZHg#D1Yk$T>t<8Ep$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_e paCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1nt|#?Sx& diff --git a/extra/sokoban/resources/CharR.png b/extra/sokoban/resources/CharR.png deleted file mode 100644 index 6e21bb3b5161518fda0f0b73d41a4b8b8de985a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1474 zcmV;z1wHzSP);cV3cv%iSfZ;=vcv-(Bzb zx##_kkTj1-@X6+Au(C56*hz_sId{ufSU_@dL;_U@5CUea07BaV0$TxoC>7Vt4u}OS z!_m+V+xqmQ6?cH&s*C%_5+#`U;0jVwiJDUYqQ7y|RXU`cOi&DB0OtRCN|Bv1&vpNJKt{=g$!LF)vVi@On2lQlu^W&p8z@AODH}z z?-lr!jR1;T{5EbyCMHuW!A5~Z{p2Fl+}A{WG~5twXS|9fQnrTX5-{d_FpSBJT~V>v z=K}C&cLl)w+Ynu%)wj^BfQ@Z}30o0#wQPeX({4EU+RFexPNWB#v99EQ3}Egce0XFJ z)YjG}DEFY#WlT%l4{)QK1wkQ{6liRTc4T)34L%RB(8a?EB?lT^_Nt%sBUeasCIC5g zoj95Tifec-vUsUkHK?YcBv1pe*eeUjY2xD96i{4?Ez{x5y(eJ|GG#>#Ag9}*QD|y3 z@sRi%*P@HGEi>;*m?TTCv>-Y4w6`W$6W7+~Jn4T$`E!y~O99&3w}Ab#7EORc-Jp6| zrJY1lWeQ*LaP+(B+GO5i+8q{J!3af`Xusi~bZTm9su_jRb%sDLQp_vzcxJxzZF%*$ zf8YKW*#yu7`N#Y?togr#@U;P(;gI=np6Pt(tuLVXjSe_u?a~AoTlT`Qp?VQpS8NE46q!%R4A|_?`1S z=p#qIgw;tWyXl?a5G?sd!8;Kb{zfnqo)ZFcVq#Pfuk;EULl@-c(_?iAi7Kn!RVK#l4~nG#QdpY1;@C9_oSO_w16OPo3(A)u}-~afEA(yijuoW0;ttP{kK7tT)$yJm6ECC2M+b1T4PkMJS8X7E{g;9 zo*88IT$i8$Fb|^^R9De2w|X3s<;gP6!XR97e?RRQX3t^0RST-Cjp9?vy8rk9+ze7F zpljD@wlt}QM1vSGl(<*qtSU7%VeM24TGBRBZ2;(av)m?9peZd<3X+*83>!)1VijAW z7^qwq`p4yNzwQw)d3eT~ifvZkO~LAnH(}twcBu&2ekrVZ5YY zBrfG(*@+*mac|S@@1BEaUpWj-O--U|cwsMl9N44b4No%Lp1|krzE`2i2eQs zowB^HhSw2*0000jbVXQnQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQK cGBibQV{c?-a;OG>?f?J)07*qoM6N<$g2unD_5c6? diff --git a/extra/sokoban/resources/CharWalkB.png b/extra/sokoban/resources/CharWalkB.png deleted file mode 100644 index 74d981939f8a85f23358687fe843ae82fa995264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1492 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 diff --git a/extra/sokoban/resources/CharWalkL.png b/extra/sokoban/resources/CharWalkL.png deleted file mode 100644 index 465e48b412923bc51526a6a923c7edc7b0310515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1544 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 diff --git a/extra/sokoban/resources/once.wav b/extra/sokoban/resources/once.wav deleted file mode 100644 index 3fc85b03d32ad9c8d2a2e28771408c183ec1605c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44144 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 z%0D<=dzI2|XsHdx+T-Z{L^3&5n|;Wi5_QzYtGFD$9iJ0VidU3)aUegR9YB|jDde^A zsbAK6>fE(U+RrS-s%Brchd5c>18!ljx7Xc^d#&A8PQ;#R3dSz&AJtWMDJzu~$}xpf z`>CvUMe}fIcjvt6WieHE?i06tAmU@Yz(2DEE{6O*1C&bMl z$)AM(=V+U-Z&|ig&;HM@;T&~xxIeo;x~x0EnPGRga+(+Q)!Jq?t$I^ArCdeL5r%V5dhlLLO3HCXCD|RTdg*X;) z{w%knGto|1o2>cPX6uGU*}3h~c3Pack@b&x*tn+O&_cDL`bjydTvk3P*>Rii)L~j> zy{kc6<(%7KKKCQHsJ=i>WyI!EG~PDeFWwpz__y> zd#xX>oK|Qm=3VosImRqv?ljUG9rWee3$==RQTbgNsZ3S&;6@v%C)Ms+d3}sg*lOn} z-sSLAWHD8Mt;Nei2I+xRJ^qzf6pvq)%1hnFMuNgMW=GN!W3wWQiHku_e-}{xU&zre zR@6FYPB(usvzhmefrh2G)Bn{3t&jRjnTE=1r;JioBVVekht*bEA-$auwNg9ty`RGJ z5t3TK{L76H_KDLZE?zlaJ)S0hN~$1@LdKNhcd;6shRPqUMD_~z0|gt-Cp)t}(ju)T zWp+j>*|sFqcmq&muUr7rqPB}AO2+)|3E+ts>ScD>8&bOXcX1|uQ2Jh)FRm7b^AWB+GmF|8y+*oWt>9np7q^=8v%SEw%n>GS zE;mXWC-j>7F)g>YP^HyB!CXxFiyX)~lorZT)Zcj21E<$E5+>~o@^Xh?$n~-OOnpui znu_J6b5b1D$HmV`Eu`(@EnySih}+I2sMN8NkygaAfb^HTU7XJLRO_Kx%{*aLGp_1Q z^lMrTZI7ByU89sy-pB{#J@Q%kqnuOet=v$WsZq_*8ls;SbGCY&!Xl9;u@+1}E{D)X ztR-EOGU4lGia(PENq0qGc*+0CIZQ>me{6E(5b-%^=HGLdI3w-F)_-O$^LNA72kIZS z&e~nIo_bnopnR6MVCv0~*U9H)N@=VdP^zk$s%SqNDXs6FecphuFyb|4I&YSw#&cCz2w1|d^=@LE~ji%@~IEeud^EuOxf<~QQ<|hSL``$um|{1aF8({z~y7{ ztI`nZt(a5HDZJx`q2}{ZU876L$6kVAg|fIGygYuB)vn!g%5^bcAUZ8}cZ9$#*}{DYiX z&M4;rW@;xdl<&&bltW5SwT-q_?`)2=-?)>5%H+#vb9x9{nV&B#6@QSnNsp!1(kbaz zDG(cqy@Yza%Z_25QH5juBYO!U{M9GCwV3xmS&hx^#-I8Ljljg)rhEsS)I?4uTM0Qq z$Z@&2++JQQ$8f@8YFTZ%-o_kZEAHZ;3F$_A(v#T+{3_ueRKy;f?i1=_l9UQFVwy0F zFT@>UveN@&dm}bcH{9&!_s%+F?G{!ovw_h=pQ~L_GpZw%Pxx}VWj*mA@dQZFN~D*o z%hP~gx+z)IoZ6pyJ9Df}dz*r8Wb)V$dNEs{-z=;W8zUan3hA~qOUjIjUoOnyn{qFi zHuScb7x{sl7pi_A&vmxi{j6qYU899QT-%^(N+ad8+!7e@DfsO*MEsCQE|6GsC-P|JH}$%<#Mo=)b5Hvt zi1g7Z)MjQl_Y&;-0D9W*V1V0jUaoMWozV;UqWuj}S z6U+=w;iKYzVijqIv{qV*`b#0r6Q2pRU~}i#9*jw~kDZF7BKw4A{i4951?-FFNTab{ zLaV0sQBI)ZUL>}GO@C!Z3ll5x_d5w%ZX=(O2P=bt=vNx&t#a-?|4$-obQ-l99rQZ? zMp!TAk%mfhrRh=!+~;(}V+5YR&CX!b(=%c&bf(Rr=Xde0J5B7D=5*sHy_i;B?V#*N zz1>Z$N31#cnTIoONnAu7{wN=jdnrB8(dHYwt?%4J{x5_VX-$n{Dsvn7e}xH9Vp~e1 zQ0)yQUz{L579=4h|ApPaRHpxp<%*6bZ-se-NnXPF#r|y0H0tPiw47>vWjPqprNrWI z%=W8lH!ra{aU@|U%FEm3hDr-{uQtJ0VWn_a`i+Q(kxEocCLQ-XzewmLeio}r-K8#= ze+hA%_*BRuNdiM5XYOG-qWV2_v5onRBzLVUlBT57etGF_JBL*VXH5|a|Y zC#FG_T$@HL?gXG`I-$X{sHXvyBQmtC4CBWvCoL*PQ}&cRYS3CMF|q zzQ!vcFOnN6ZPcsU2IGcR&wb)gCXz*aP(ztQ+$?@2D*g+mQdg-R@Wj{ieL=jsd}%Jq zZl+67|3sNc3u0ZMdv)Bkb_Q#iQC;T|FTFAhwZ0W68=n}H7>hrr;BNOP-Y3dnF7;3* zsS*8=k=mZ*W(|%IRiiV3V5)J;`L#k1@sn6t>L|6Bievtb5Z?*~5U&C!v3uzss6Ej% zkuJo(!1sP~HzM95qp}{Vx{^}qA*+cExWx&HKXAIKxY?DcKrK;QJ|T}&)~MO^s9D-x z=T-==6AhwssF_S@ZU#SBXd>Q0hBlDuN!g?aVo&j|kQMh?iu0N6ba})}5$R5B3j(jU z`;VPuO*4wSCy%pAwakpMNUb)N*TTBCeK%ns15a!W?%cM+b@WaeWM$` z#T&!_CR7yv72{G#{3J=|#FpX(A(>E?FUqm(Zn_q=FPawjxiR?Sm2fB7Z_OS?R6no& ztGqy`yqTDbc%u+;EFyl*&qE0_Q6GxPUg&lc^^xW-J1^#YHF8t*0d<6F#x3G!33bF{ zVj8KKR91>hXT49ii!JPsjNNJpPM|N;uzNh&KXXZxpIwHnQhN zB85Ck&ZcAogD7YevPL;yyb+;F){V8Li?SQIr~FBwpZHMBhSL>5ciACU5w{2lKF*8W z6J|c0i&`A@$$G@>;I@~}?Q5SkYZ{NiE>|fR*OEBL2>>Kx9yC99@mw$2|jL>Mq_8Q%eP<4AOgXiTIs3SGdV5+&gwZ)0LKE zU82XyR78tlk@wswZqEl>->HpK$0>W|@8q-C9eu6#-w<;O&bJF1Zx$em>gZ-i(aq*r z&zzS2ov=w{W^4)Fh&{qR=MSUa&xyR06}S0FoFt|cM+%4ehukH06;mHPuugP2sfNXa z5#9kOh2788^aWa1wXd>9&LAIy<~ad(`L!O#qi1giswgP0lzS@UR6;*%ytYcaJN&}L zlE{tNZF&s*jtlua!T|9W@-r*408x{zP^jLw44K0<%uJrMA(ln(gglZmD1!kvv+3D!^Q2 zGxNm-Qr!404h~qko}$(p*EnmLP~T#P_I& z>=G%RMR)lk{46ZscXI34VN6bXZ!B+gGUid*poO={`DitP<~dqxfa$ja=R1q@O~YOO zfm>aWSc|VGLDfpDBm>$Fb=l1CO!H!4KXQNcGPQ)s$#sB!E{e0n$09AU(i?G;SO?Yq zo$w1koa@4tU~W*IW0xa^$>HGpy5Ypa@QuDNLi8_-@0#Rp9Kzy2Q;y zIv~=*N^Yo2d5wHld*`xOAzVwoiz?J%ra0G&Zz05yBM(Gd4A4dA0L^a^IH3|>k1NZ% z^lBjf0Q9q0QU@h0HUztPLo#1Ha+@(g9YnohrOytRtB zbA6g<6`2zoLziUdbGy*Zii+#SH@Htix-Tvei;A0sm{9K9`2u<^l@IvrGf_Mo5N#5~E(yQ`p-; zpF1&)wuuSEbH#huP2?6A2@0PBnn(ur1^oxb#)d}D5-GxZ{-5r3JD2sBQBZ%YK2{=1 zSKQ}5^pt7noYOIh_M-OE^;W*0-7G?Tp^2;02L8T8&E0Y+^Oe;*SW85$_GY z-&^sB*k6pG`c9#{SnNY)FRBf-iSNQe_4n}Kxd7`f5g|A@DGulEyZ_2 zb72{OnmfrZWt!7(W8I=B$P`4=V77M+yTS2L@7JN5O;paHdp<|LEJhtn!>uk&97w$U zhLmb4mDPD#Q6sBW8?zw{+LE)QOR09u3pO2}Mz{b*y|Sx8_y9L0Tp6t9R&#qY(dLUCaPzlfU;be)mj z6w47ENuCe+psqK~xo7=gp4EqHZPcF15uEQc_ETFhgZ@FZBZ(J@v~qvhmd_|})t~fq zW*YlPcb(4@KSzegy3!2WAJx!P;E^MjL=_oxOZ-c$3a(O6=*LgvCbKOWkzN{0741hJ z2yMTNH^Mn*6*Uj)y|u<_7v+Fl9^dac*uzGk_}!SZpTNZ?%9#{b$*ujP_cMpvdt5H) zMy!vViY=upv(vcs{171>s{Io1;9K!5A{P{Q2uVUCz7yAq{f@Z__HZ*&fc!PwTFvmzsS*kEbM5!%ZS}*xFyf%$;e=$h?x_SdlbGV#Z zzLPkNSX=RPBykT+vw?g{9;J*`uW18~mex4uG>}Vwa%FS{n8Q<6kzC zpg2l;ZJu7oY-<1J-t==4og>3yt!RsB#SP$_2%6Ae+=XxVKs)M8M?$BY>M|FH@}|GK(@@6izrEIb?t~g z*_;Vnoj&MJY>4cN&7`xlqqr%2SAi4EOdKVp8Q z1Gzi2pny(ru3ME+?PIX-o1om1Tgx==^As}l7_^C}2@bWsS8lG z93sq!7rQ|J#I8g&j1ZEGBhfXlBV*Q!-9%daU3kK0M6b@pD)cfcZ)^qBo(ACz|Bjo% z8Du>-hJ(2mR@*51@PGF)4^AOd&H!_MNo1D0%P+CnT%bPEMjCCbA>%HC%+Zp_!-%U4%n?f^*r|%x1a~bvIfgvW)l;6!r(Z$L!43T%)v3 zY7w=JvJ&0JK%A4{Ll?g3E+ynCa+2~;d9K#d-yvIkr=~wEd`PO%=hQUDW^?f=g)>3} z^y-`9Gx0odXC3i{&`4O%U+12(XP8NJerjVheWV|87)-3XJIzj*U5vPXUwx`%RQ`|) zpxUo~%av2O&6xbXyh1Lk@M?Z-zFyb--tOUU_g(1L4Ppi83rrra2A^NJB{UOPiB~b# zkBZa83gShfx-gwT!JTEdF#~9cnhRvzlvolx^Rm1Bp-j{igKi zNCvWJxYJL#6`Xli)Lg7L)9R`NluPo@G6ODl>|1s|PcU*#c^PU?QE07|PMXgw!Y$?h z7Val6M-Nh+nHwy{%RnxrfIR;buZgEIiJFM-g`~XxY`q$|0!7lzbi4eh|0$6!B_flUh~DpqA49)*GAU?6&UT{?jmHB!5hx zH!yK7FP~O8D%3_boCP;JBF+`7i4TQ_!Ycj>_kcacOreWWd!zXxy!! zjeJ0YzETd=P*pZj4Ttb^0@c7kFehH!nSXeFk1yho1%I6jC z3iZXm5$~*cKpX{}dr~MX{K+5Sj|BS+yMzw< zo0v~LAmkDTLib$3j%8}nuVVwEx5*O3@Zf|;xy|guW@Y0uH2FtLHf1qXToPKrP4vxY z$dQUl8%!Nz9g9F7h*yAul z1HLcUi>-m|ToTI?ok%_k^8~%Uoel+FL>T+DW$GbCRA$O0w~U+CJ14#0E}Tnlg9g%s`40}J5Bvt9B(miUYW+NLSsP^M2u${rd>Jk?YtqZ9 zvaxNE^w|IH^DVfHmRl*zE!a79gyZbBJV?$ZJBalZ-_8U>`3c*chDt8AqPA9VXjZbD zxYPVgVMwNk$zVkhWJ@yPwD3K8*eTTdQSnc)hWJ2e1=jbP)7b~idb&RKEZQ`(51W9W z{AJLsYg(s_E_xBIjM`SY27NP=tN@Qa0phe1ndD#O(_pkUku4APNl@gMVDhCQsz>U@ z^3x}o0_bH0h3mlaf1?sEV;)Tu%ZitTTA1uNxJT@XZ%E=uG*@IgaVPlB@9qBktyfpl zIV}~C(mpuck|W*|obY{u1a2B4zm}&fL)Eof7UQvb$9BMJ2ZBQ{i}j|XY)h^mUsL#m zY}tTHzk+NTD;5)v36+qYXThTPG9&4W?-oL?TB4w1J&O#$tz%AqZ0Cx^X9b7}U>_oQY z1PjX|^yQa<)lO#W(QjhCk(~vJ(ZOMlb6eP_(5nOOsj4Uym7O?WRym3<$jT|?vgmDR zfXb4qX|%4ojcmE^#QhrKFmify7?qP*!CvC7@iT?2=w*jd>zBlpVs|kn&J;Ah0^bFb zy(;6tzbHogk|%-Vn|iAp%j#+R`T=bnwzQeyP^^!5G5qjyPVA1x$`9neN?ElLvZbz> z*RJCB^S1!Szm1-zdNFsf<500xDUJzr6!A`oi@+K_3w?x3ya0_gGb_`7Q~6^nBQEh{ zxX6F$7IkJ?w7FLAp>S*ljRSU}{3$c`yI2v{XlEkMt?#0DFde(kF?0 zk)kn{UW4q+#U}~Jgc`t||6%s+7pIFA#oIz-VI%*Fv)T8|4ro|Uk)4|fFR1NLb6?oi ztP|K7mD4Jzzba4Up>j!Vrb4ijIHvAT^5SpXjcH)ed5wqWMf;tbJ!nNtj*O2rLoX}K z{R|D{F>vP^RNgglxA;4<lWabQ$V+v|!{<^v*1PXJltqYqe2d&!rWI z%JU49rwZyJ8NOW(>;w8idn^I{=sx`1N7>q!fO6DvhxBnhptE+fr31hxEo~m`?#m!}?{sA5~4_K)n>LCZdUUO^~ zKVhzyS1W0g^wj2C>!p+2uL#aJI@%42%Ov2kYkVsIkr9L$D8Q0RK_bGg~j zB=Un5)rsyT1!y2kyq8WDd%IcRi0QtX0vovJ@DVgbHDp9Rl=@cd7SyZOYESL3-rg)` zS9QDie}(7CE75)6nE$al_m1BpR7B6bFIvz*u3+}%$G(;os_~t{*^4u8sNpdy(wf`~ zji4;D^M%y~ll`K063C?%kl;vk%zQxCInZT(fsY|IvSqruO-p4QGS}KW+~>*)aeetZ z=q-Z~M;AkUzhgj3adE0}o9FptT*w@!`@+}LIdYKT!&?4y_cnUxabuX?5Q_D3CAG2& zXDWuXWy7Bh<;n76%=Ij4CasBn2iY>!S?k>lLLyC+q)tGMpUTaH;=+kzfB_XKX0I@7 zdy1AY1T5?W_ldp2%tP-y5-k)NPh1aD`Ayw*Hfzl{>gffvI_fkfs{D-#FM-O-40WkK z7}#5IhKj%~zw2@HrghCpcsaxRWE-f}I^CDu!fgk~OpA_r9*WBsWamF(D=22Iuy4P} z-DI~j{psZ2SkceK^5D6b*ByfWX%8c>E@=5M8@@naX@c9#fNC#<>YFC3z!5EwE&G6~ zv)j4d+Wv@eCAk5+?~=?0ydAm2FB1x35?#l)`-pD6M68W%^bf*RejE1DGngOf7qPa{ zvt%0d&VRfQPDOizS;la**FX}jl?Rx8b-rawc4SLeI3+SD`;@=boye9Q<_vqOd(2OS zDIzIjZ>h=5J2ov(3CFQ5S}#5lH7J4?fCx*A$AvsXA2@7&XWK9Wy)Kq9I-a};eY~l+ z+|jLWW~iUh4yx~!s@Q)I1yjg_sh&r!@hw}bE1L3HO{tGWwxo3OdJTh7#C+^Fn$mBu zduzd$7TyUxF@wG!Ulergi9jx^g($XDjky}Ez#OEi#`Z*#k!|o+=ark+nQJlTR(%|L z=V2u~kV{X@_S|xI%-M$DCQ)~|+p=k`^(V$c^p<7bx!?;yM8Cu~(S_K-+$3;58vDz0 zIGurhwnH2slHvs61~2hxIf6Y;cSClzj_f4JunL@m*X*+BWj*w&+E3~%B?cVd0(p`J z-K7vV{Zr*v@UfPKmivdE%Dit~bv}Bj!?I+(XkO|S{WJSFcBccNNK8PL%gD|LP_SBw zn$T4^$baHKv-g<=bUEs9G-qT4aWbI%#_keZvZfogz{1L7Uu2?}HO0xYqPrAFZ!y9DhM*aabg5%6+ zIy1F2N=2H(ll98`&K+mJ2JS4Zr_+kSyED+hh`JK)?&+(fnoL*Xrp80}8(g}}tzIW)fEd>Dz8N#H9T}FR0a2=O`TZecf=ACGh=f!`rrB&W&uDtFG5b<1h19 zyTALF|8IDgyo0@W17-*Ng1gPH7D_-*dWmSf^a+Tfw@6`^d4&%-l6%jrrmLY>XOHv; zXa9)a`K$fd?2Tx+a#m_+RY|Ak8U$JPkBl%DG(a-7iaZXqj%scQ2Zc?9MvfqH# z-yC&U7Pr|AojM9HYd!UQOd`)XVr_H|dryOaV50A1f79vM)?8=4n(z|NjQv0nF8(h~n7X*vt*Or5GmZEsoL{N=Y+Mq1k?x0TXc}2d zybJRA-P}WVHfx*FPOk~)*E%J)atvyC2lUSth`SnI*3Q_vy--7~tr3`)?c44Ex9^mC|ZVmWX6x~Y(VdY@7chbpZ&ov8Tva4z? z_!1esrWh-C0$1q_lym@deWB7+t*Q;tUt;o&b|!iog2Tkw$fj5~`W;h-!&?#I2GrcI zI50$ixdTP83Va~Bg#r9nZVX$Sv8k~!4bHE*;Wc0KT048JQszB<2PV6wv_Y?4jd|V{ z@p_{6F3S1fvmT-j*0$?K%=gx9=M6lp8Odx>Kem<5!}j6^LoZXnF^^*M5t0gxbs9Fq zo8kMa#<%6Fv&oq~R0U+GMN|q$_y=9u>1lm3mP7qtsNPfRDevG>7?1lLgxlPRuh$5E zlkMO{QDeH<*skUN=no0Uk>jFGDUa?6?f)Ne%v9Kf-N5NM$pv1TAr^)P5`}N*d-(G| z&@(YI1|d6{@Oys(UTu^G?i{IiN3Xtvc%M)K(=mf4LRUSHeg5xCPSsXfy`%BTJP!5o zynjFZNZyUErYbQj*(=;BC?L6j%buZAOOk^b@dv8!Z}s%1!9?jd%Xph^A=cQIeiAW=2dT`zo+_v^*vmJ0} zCg{g&l!DOA{z1NsMa1QZmkVz=epIVy-SnHrNUOQi((4=iPRxw-j}@bLG9s7r+a|05 z6oOB}&y?+e}yvP2woKh^YbJNe%c;K0tr$<86Wyc_dzmyw%>Snbq-1GUY#D ziP89Wlfh7)$dxe}MyUNUi87m4;2}8ZT@GFmZzE@7!)XT|vliHdy}%~y7-~Hk?(;45 z_(srNDhOks5zNKrl%c1B71blBhv$99YwGN@ikSEH?btS0N^d2U4`CNI0f=lNHheB> zJ)s;{4R1B^)7~K z{%db{_xo3%U!93gr*biWvj1{BF=FJ&6$1dUG5TaU^a0!IA#o)0TXc8ms};bC4g~MK{O$ns zvVPc2<$%v+4OrhbAhU7Mc_tz5Yq^T@uhLy@q7BmT8NXWfoLXMfpa;<%>S~Oh#yn;T z{w+L$Wq`(B1DBJyLtC~TJ(SKu%5tTO zno`T6_cs*m*q6F%;V(N1&NrMAnZfKDu!g?KmWjaABI2c&5;$oSu)gBLApSS5H(P|c zNHqaxC&*G^KYy+J(QaT}HOA|Gvf;`V&6lbTOi~^1w0W2WD6zTMC@G1PMy!g7e?8rGWAX z=Ua>n-6&tjWEhW)_g(c091Fjh`EAZ6d_GKx_y13!mxb^x&uZOLEAKtAD#-bNdyo`FX28ddQ1>&?LgOvp9y-fkq^Nt5*##u)g8${<^65jUKy2!f;EfcW8J}uULiXhxl8T9oNLt8 zt3mJFjh99DF<~d8`sQMzXv!^>7s^s~7Sy>M=1FU=^Sd`Yn1{*N8LVLedRc^j%Ksze zg^%qv?o)z8@II>HYrMGdJzpD&*(-V^rA6yUW)qhJ#VZ4r^41(-l-EmXZQ;VIpuEDl z7GWA~MYd$cYss|8mb+R?<9D-&O}ZBRPy{RhN8uQ{!(>7)lduV^gGu`ij?1t2c^`eW z1dt0MW<*B=}XB%4RGQoFFn{27zBgz!LUgH6$A#7l-=eF?of6@D+nB`9WZ z;b84TCt~fQo5@dM#-O=32kLkilQEuY@6^1&xw-KD_CcfG4h$Fpr@o{NfLo{?P;OaE zx9_`mp^e`qcSHw5`)|!oBnn2T z*fHR;1?)j?Ek78Zldm2S9lu4u0}fmwRu|6*`Gn5coVI6EGyCBXoCS|k3h0lc+;et8 z?7au;9kem(6}-RE@b+aDezxNkQ!3?Gs8@U7Ah-yWd(K+wjKe$i$?z;RixKpA<^p=z zRelb(`qL1{0a9|l;p)obQEY~Pf{&msOW}n|Jk~F=mH31gF|FLy@T)Ju`_D%3&|OxV z1G!wnySKeKoet;K-|%&QQlDuVjX#hrzN30F^sA>(SAW7DljYJwaoHx6Mut2VBa(p0 zcN3Xf<{Ofz1;wm5SlDQ&|5f3yK7hS!%`@NTP9B&Cv zDIMVdD6IE``)Z!u*X`i94_lFyqZGBArrE04HDrWeueP`uoINHn!13qc&&?<<7T)t2 z_;j3%$zF__hj*Ir83i-FTTUT+Id(U3J-yZl)mImK{0(^h&tfiQ#{1|O${6Sozv#Q6 z27a(ly9fOP;SO?Yv+BqdWAD9wUb_j-K1s;|J^o){h(pkJ(&H8O7u5O?Z7w*`FsqD{9=~TK z1;IvMMCVf3nL+GgZZ_XsFofRV>>tprb#V42*e%|IzB-X#!OcN-n$(ck?MN1~c{tTS z1`gfRl8trnJ8!_-w|-a{+{U-tjhy*}xjr2`)6?o!?V4V~JcHgc9GjG3@GMl0y{39I zd)YhaWn+cZP~fkjm+{{;g0GIm3qmnC1SfHQu$wwd)r>8RyntV}9ys(RyS#PMn5Yi~ zD|)MRMZD|sVMM$pd(h!GKuyx&e9VI0Qpi@p!JY>%iHng%v5L_C4Q!^qZuN`dOwWMJ zQh{YYMKAjvdTuVEJ*uHKn~d2+Wd<#Whe^EFU{;Ryu{xh;aa*g=!gv)S5Z9qIyqNUH!k%xd4jmNej#`Ab@ zw}AeRnjU>jrYGuyLmz{Ce7ac_uMGrD_Vr46u&~qkdWYouatfs2nuU7+W7fg|w_cLxr^7WBhd_2>-p zEOs{qyuQw9ye5?OE7}t^3pUZ;0Vy2-f@s|A%)c?^+PURtLeLu2A2Zmn(j`Fp)NXB3@$$kXy#pNAvOFH1P$LOQQ z#oYphw>MR|EbLwAtM{TsBi*pOISmg_1Gpqw;x&6t_<{E-H5CQ9`E~ML!6fRa+*Zb; zm-W_nVe)-|_wk6oC)|c!R)e}l7iT+hzhKfn#H2llO+!j46DIp3u&{#S3c=vB^Eo(| z*@m}FtD`2FkLVOk^v*fS?P+Fy{CW)ro6LWd(#m@vz^%xZ`|tn{S3JC5nx$>lL*q}Y zx|7|@7$gx)RKjFCaIw0(Zu7zL{{V&xMPJ<|*zbGlq^*J)%3v zH*jTC@y5Y#+0=CPyV^%g_NCAW-lNucqT1hqVJ=Y$sqf)@j2Ycc*E;H~@)iRpjf*sj z8B`x;KYNus28U8QAlrvPNx7w5P*`uHvn7LD{RpbzJUf#qNpFcIi#8$u2zU5T++5Bm zi$`{@Lw3g1G1%Tb!MEFs+cf0{%6{c%yr<2K7xX9bVyc9j-A@xrq!QVW$#;VBS&sk6 zFA<7jxA6?|GU4Toff?TgFYW3HfA9;q@oW|5K3LKE$Oj@rSjQjk9)~)<)94SqbBg)` zNFs*bxe57l60h2uDE}$_)e2gDeX>DW8|`s!5C5021z93$$0pOtw_X+#wg_dxQl6sv z(n=yUg3a*fUWa1V5tF?!%YB>dog=G>YXRYxbVu25z*4@4pR@-!dn0HBr+~{g;m=V1 zQMsuMSDWMg?hd24^~^rtZt_=#^P$BTq7Knn*amo)k_p*a6)fc$SYIk=F3+&NsU@C< zPoh5G1~^xzCr~QcHo67TK~Fs8dk-;CB+NR!3{g z^#mqg2`BDRffs%vPl97cnAYqBZWLc#cqO#OzEs0~X2WcFg*j1GJn{`!SLU)pUu{dB zj;4g7G!(m=dr-$$;5Xo<{=cTq15U28?AvE%`)+zKq=%3~2nhs8s6m1V3Mz`CV0%Ha ziv>SysHkr~eL=B;pcDlXs*pfPLOQ9C1}UVFO|N8=?QLexdtJ|y{e54~Z+2&AXU~1^ z{=dtaH1=W}e;)L*b?foY-e7|KzyRm*%!;!}8ns>E43QqcA;hV|L*)xl`aF68U z+{N@<<=5%Be3$*J7Vfm`N3`AwY8uVG6epOyb*k7__A9LO8%47-N7H_VD{?>Q&fy!I zi<)*dG;mk@lXcVJPvr7WZJx~ca@{mG2$IIBO^-ES*;?6NpQ|bCO;%;^qvm_O>~MK& z#jeT+m~H$9e3a)-tseAqmvS#fhC9vw!@UjjsEW=g{Tuzx3;FzozvkDpSG0Yb+0BcM zf2L+H!8(V6<5ysxo6+9&#IjrJCpJuK{9e;OE?-k!wy0>f~`)t{& z7pf*>o!h~jox!>L(B2Kq!ltpm`as2Z$|uuNy0ZA8?2e>!Iwk)tIz0X9R)3@M_J$dJ z3don3-fTgdufbyml=f!bH|wYKc^MBk^=?^7hv2vQ|7QQ{Gevz$o-gfI{=tgtDo4-( zxt7XnKQ&Qz=ljdZ)*5? z{SKm659*>d*ydg`?KkMH{)O(`jK(c&#rJ4C#Qmn5(-oP=iauF#r1a|YAJEOc8f&?Y z{8QU$0NU$DtbU5BZ$0$BQh8^^r-{{1(Ea~>me2kJcaCkpo4NNr%-OGHU-sR)uh#V? zx@;qowbxFp`)geftmUPK&5h%mUun6k?W4J?3zsA#v#oSj$Cdr8d?xoSez_`N^+Rgf zLZ`mmlUYeD`v;Tg`Sg#cRbGX4ZYaH(ov1F^tJ#fzJh!Xu+}5Yr${5aE|10(D;IA)T zkUh1>nQGiXO*E~(olVOD;G`a{+vz?&$6XD-X4AQm{j&Mxn}}sUWlsA`&~2XnV-I4> zS}NQ=oqokEEXPLT%Cc`V$^1mopE7T!P5BAAueGgixvsgjad$&4pSd@Ser^_|v;~UY z>aMR_T6cZ@z=j@;A8mTA`4(pSUGk-Ab5fmsr1%4+{{feEuB@q?Ni2I16kmcgyMU|b zvaQ}&^|`7iE0>0vy=&=x#fP$EGM`I-%j~A8?e>=Xrso?UYFJQT#=SSAKrU|uT-LSj zv(#XB)K8&z{BtH7PqzM~{f_(>(~o7&FRCfNzw`uC_6sV9usMDsmDedU(IEJ%p`ZH& zwuWw~no;>=#qYSUeSgW##V>H*)DUX+-?XnKv#)BpkACM&dIa}CuNF_(MrIgMcPFvs zzWUqf?<{G$tmS0un)X+?tKpxSyNf1+%SN;Pcw6O#O!aSPA1X_~WjxWki7fa9ki_*> z_p*`rBXy=E}vg| zS;@bPj%P+DA1~aSTiiB)yFjmO8q_$3Ethp5mtI)sd(;fwr~v2IeVETuYHb+RG^6<} zKDBFOZfRj|@?iE$)R=ddEiK>4=J;=_28I4yH!|&TkmuXX`ucR5K}V^z;$-=vvagix zDZYkn;5V2oj?CTBwu-wJvvlLr`YZXAsB5v#-Jrn3)O??&=DUeZ+aFxE99(u``^fwm zX*W6&uaaq(loeO>W}oe)s%fC==1xPnXLu~RXk(|Jf~&vB-oiT-E6VRHJClx5b9PGR zJM0W?p=O`a(y#elKBHrQ{djQoG-ku^Q8Uz0^L@W=U)`_jKS4j~(Wb$~vVZa^dcRKZ zF)d=BbZ7lU?uEI5=vl{fy*tld<=(SaP;NW>H0xS^)HW4s*_}R_`Eb#u z;`2&xqw4#3Mc2wFz=B_{dZ=m+IsOk-H!~&rdu6A}uT{({UtPAbbbiVG#WxfcGEXMc zk>}rYx3-_(b`~D-mFC$^!&PXjaM|zXl!o$MbpIQeDl$ky4J4kAIiMW$wDe0Q zvx*NE^d{-@<5EdyFATDtSeXLq)&YMI)) zu=Uoq%J#MG59aR5-&nXb?Vr>n3o>_R2N%sNy1aO9asQHUl*}sGMSH!ZG+%PKWMRqw zluRpWD89dVOz{gvlZu|o_R0P%vpcys`Ad4LaARR!eq8=vx$(IL?YFjIlo&bj}a>zRKle{rF@@Z+>!@_ce}Wo{4RqngF7jiYZEAxNJx8!dvtSU@RpG^BEKTh@}Q!>Bf zllppQKbrk<_Q~wh?AGj|aBRu0%+AWr$ljWrn9XHYXYR{fm+6#Q$|umBlk7fFqx%z;cprZrRGXviGTY{@Lk{5vxv^Iw@OGyO8Bl4ZRAOUcBf zg}?qo`l)nunk%d?JX`p6;md^&7bX?XEc7Y#FZ3;pDV$%psqoFhLxm-UQ-u-fC(`@V zC21iYlYBY(ZL%QQn&hE6o==v%HuEVyCGZQGFY@)1nGa_!%Z$wo$fU{p$;RZBd7MfPB?pstpfo?3ojjcU9%^?aALnn* zNZQkVeA?bK>4WKy)32wWOt0d+BhvwCRayb{(zGP)$#qQR_0Oh1NPovCoxYLog~R^I zq~t@%XOnNBml>S#k>s&tX7X(E9LF=stmMh$3Ap-m@|)zB$#;`)C7(%dOs1m2UVN(O z`{|Z+MfwWY{$Tpk^hfEJ)6bQ|BdElBg)WEvVAk@Vz~5^Le|ZD_uh z&P<<3|Hvn{-os~$ew)vUy*>R}dPn*_ewxAS|4RRZ{@zLVq|Ipp#UaT!_`Eo|BDp5{ z2on1Yw7-a?Z%c0H8gAp+7m&d%$tR$9O>%W|0UQp6$Ks?dJ%XIprEAi;>5J)8e1_@+ z>3!)h`83tL)1SfhZ_?kV4?}NGx`21>NRLCYoX^G{$Q7TJj8D!>E=n#*u7uxflIxS} zl80xBG9*NCOpXJ;SVY`1wf5m6F{u*iz zq>sY=9De&I^bV!}R)#-43U2+3oKZ3TeN-jeK zayT%lN{aA~Fv zaa@juui)!celvmVI+H8xi#HYriU-qe=x8bDelhU)X!_UmAJBY)pZ){q%aG_cv|R(m zV*aKlM}Mddh1xiDc>$8Wkgt>ZIwi>Wvg89$n;y8nfa@8PjDlisC>A)!VL04K-=g6}u5sqJX6Ce7oAov_k=@HdQejDn&Zj^i9x z)g*j!=~1qJUAhv#co~lV6(Y|gr#1LI{4IvwHf*^z&7r|AcG>Q zQBRqSBrgh&$;fy-^oAhMZh^lR;#DxP7 z;rWwD^c5t!4v8KK7TOhS8HPsW=3LG;@wCNENaCZHpa$Ps(5oVzwGjCarn@-XIy_<#yu1vZ=aA$x(0l=XE(j534f@jq3uL9fT=VE)85crl z3Unt2UX3vN<5|#=|B-wjjBO4K^6ZgR;O%MC-? zR^(n2_%phk4MnZd+#r8?gS?G|(l8#z9%VU#_YUC-`(b5f!8UB}ApWoc{Vm~ml|wpD zA#s{L3*2m_ZVQ z-XN+P%DelbyG}uxbt%j!Ch$Z6cR1PlRT5i>>?;l17lAQhGC7j!g`#jX-at_j5z^lvn{RZq)i)jT>bcVm7T)z?ea*nG4 zx>cr^K=C{dn(Y zl&E<(Voo;WkbdN^nX5g_Rd0db8}K$C>Aj2;U*J%ObNFd75`Gig-G#p&hh7Wu#k#B? zx``S7LTpAIUIBmB43{EJV~qL3Oxv4xn-_`_K0qvF2I;LpPp<{8Ucff>hv$O+7C=$k z+|D~iXD!5+D(r0#vKq}f&*j_~AVK}z`p8IgAyS@%thJaSNW$n+3a)O0Kjpa{d98$x zxlnj9cwWpz&m!Hqc)Pji-M}6HQ4!MYgp3Aq?V~xPzHJPXOMTr4Fe%`daoE!^uB$J$ z)eU`}YvTOo7@3 z@I5j3-!R_Uhrg)8Iy1>h#J5&r7xUmoOPPiK^uO6?a1s2iN1l6-=P9a{glOH3 zYaWcXoQ=JR$E^RPb`j5}2JX(~H)G&`2-npcX;wf_?>o+UcAd`b%h2DeP zEXB_kz|||zdKrrP`g~qp3%woCI{|lS&|i*bMN0edoOUWJx+`3gV3j$f|9*LPr7$B~Ej(i#1o zfgOy51Cgy7RCklHm59{zy|M6b#n%(=tccoz_70%E&CnC)nv0|}Cp>(%AkY)JY=zzd zthpI)sNfuWdq*F}>eAePDG&2|#1kUjLA=jM9WzlqXV^zn+=M(=AWid*@zSr0;LhkK z?p%enY#}EfguiBTLm4va!?h1Vd-}uqL6Ra1xzs!4&U!Z5ragjoY^?_EnHx57tiZ<> zhr`OmjIa>RErM^6($=8ABShOaET)2M?u|UHZ#}ctqQ{@lp*AP-n)J*@;s{Zhws{N- z*d1c^M(8a^Q(DJD=q(FYqNS|nFjrOc&J$c=8~#uZf4zw>!;q*IyFO@DW{qNntL8?* zy}6+m+Ac+Vt!VEQ@;r<@?S+_aS3+k6Jc@dk^X!el-Dt=pi&9&JfY$F$0{q;kCBao!7$XaIGhZp*Mt zQOHni+Xs8z?V8(%lGwgxhe3u zgLfQ6=Phv9i8ES3+H*DUSi?*A%plF){I(2QnGiKIVB8#8&rEa}4ekqE9tidjIeiC; z8=#?8u7^9h+#FD}L z<@t*yI6Mh*HNqU>I0*HF9QsFfhybEZv(P3u6Dx@)ys{c3TEJ%PfZ9V7!$d0`1-;?O z*`6c+r6JNR!t?T6VH47<3I3-<_w(?|rMZ`%cA}}Rf!db9=~iCZh9s=r4-+R^13v4D zy_k`VF=wJZI}+v}(Mnf%vrf+=N#mv%{(b)TXrQwnTGBhjLm$}-y?5cp`qIa?;H7(c zUHxgHR#w*kL!f7d*XPAzF+%r4nw^lOIYBv|f|kCZ=8R`r=l`$6J#eBH--fOz$-cF} zw+gN!E@|UYn)1`p`_$Xd?v=jbzB1^yT zLZf?m{b2A|Zr((DBElX-D>LBOAW=O-d5Vtg0(L_J+DbduR|kJeP>qOPq$(!#ywyB2 zg6~3uk(xHEmX8LxG^39^^eRJ)v9B@`ns#-RY>d+b`CWJTD+v;<=kN49&#&Bea^^i~ z$)Dv>+3n)1zGxle&qmr)=)94m4gN~Gdi&QR>|uf07`~6@VgGypzS5m5Dki$LgvfFj z>B!S&4t;DZ9=?-Td~G*hy%HaCegJxU%_-#4NTkT6BFXO9yt4o?nD!#Fwb~m6HT7rK zQ-Ahxj|N`M3L7}AeC%TxJGJ{=L1$8~=FmTmz?og^CM?BhT@J0@=xziw%(p)DKr^3F zwFmr_@UB*5QG+avCObI4)Yd{zENE^pUh4zdPp-*Mgpo|Y(+VS25q(Kd zOuHzcF_Dq^Ta+s32)YWrJ+I*vzXOm6(&Z~GVRPcs~O4f z&fuEtP^&!=;8DCutZ6So9Bt=+9u-QYxD=kv=kLOuwcatfv(r)nwXR4?t8^wKy)&UQ z3TmUFr(YP)2Eo0ZkIrZ>gSAL+4`*|x;iPXNlp?j)pt}%Uy#lW=x9)+z_u;Mu?yUCg z=Jr6EqDp6|_BD+uaRz5LGJ-n&GPhfOC82Yr{@z1JYlAeEq?Mi(rh0rm_{Tb~$ZR3K zR(zZlDWqh5(jOk}hRLI`#9C9CIv*RwD|T^v@tz8<(A?01MvT*B?N@OID==#?W2eZ>JP_xpW(l>bx2QjRA69%$`A$Lc zK!`9K@j|1Rl3fPnMc9k84(lT4M7!bdct9Zbp|sFm9Cl7cF3y7V4pF^X)=Y07X&}^k z5nn`~NvJX1VAzMeVt!Z?V)k-qE`g?h2y-6U{(!Tp63*t?m>n#eryCVUy+mIQjsp}zqg?}ncBf_cx0yB%H6 zEzWgkqbtw5@|xWvbu0J1ctv|D=MmAhh{EZjNX)#n30|x#|DPtU*wvu36fui2Mw>B$ zD#-ynvR;4LLy)Xlh;)3_Na_Je{Hgk6VuRgxoFEFNA;aWjNdD>mI zL*T81y*Q`R6bp9eC(o_ytiJqie(W5sz^f}qrX?ZIi?zh@JJFJO=}n}%lEWU1_WCCB z+!CV93G{6~$^;+o4kcyhqkG^-dX?dKk*4i)=HDMe8z|8X>ULF8`jF1A<|tR{9R zd>-Sr618WRg39DUEF=;%ek(_PtrAY`XS>Bw#zTZ70#&Z%99bxu*F<^ZKPyZ*RFcb( zsrC}%_Ip_JaiUBUGEF#FIp@&xqn@-3smX(ATI3eFl$M%Qk8Wq!M{Xh>A48_1>20TN z#w{0n$6Bmi0+IC*=;;+^3URJnTA5ojcjdVheZ7pI%lNr6ysi~>g{qOz>|_NfhsQam z9W?FqE$ApoyDsav0#Us+kzM3k&|N!rqi1M4Rh&y+wGN+~|I46ZT=0mp_ImVPYfdX_ z{o)`9!&#g}uKR*??ZfY4%-CK(Pf5MWABP%D`6#J-tA_l%*P#Kk3P{n&l%y zKx_7{Yq@r7+P$YGsvMQ3_9C(n8Cs(mXGHXFyd}s-T}jO|Yc)zwq+~?*u#e?WMtQqY z;z=htbx89tTH1x|-VXYcH}^p7Fs*~0xqdJ2I?B79!x?KboI#vz6{}5j=KRJ2eZ}ly zY_&hC=V&!vol(DmGsMWYhcj>G{Mw6=R4qoE*%snxq-Z`gU*rSE&<-O#Gl$;alSpSD zs4w5$Z8EwW@x(t_IBbSLt9awgF8DK!YM)jV<|#3_aZUcMZ;x<&>aoC4fmYO7w9qI| z`LfGAFg(uSxoF$jgIgg9I?S`*{AcxnKdSG?i8M+qzMG7hI5(zBMH{fth(5zK_HMl?w z#ed$4Jgv*DD*FX($%(mMO5$FpjG_+rCCrA#y8?PJGaU`*+5{i=A??z~OusTj8Z(vG zqD=SmUi(>g==JSbySUfjrk&kotHPlH%bdZ_@~szIS=*Cz%PrzH{oTIm>LAIE?)3^@ z5j(wujXHhU7v$L#{7}!<7DY{>3BPt|&Yq8`(cGm?Sy|gfv$i&Z>g}5Yy=W_9G`sTl zT;2E)2^@spQRvmeof8l9cSNMx;}9fg_28a_XvTi4Q`DZpb4qkt@O>lnj-$POaObAY z`e2vKk?R{gtm~C>w3fZl(|61(DPHe9ybI@4b7DhjiA$BE-?bmHg_dbNE5Mx{Y@Mv%?iey7&(mAY0p*sndds)7qkoNd`u16LAH|{52p>%veTq>8pmp&Wyj79 zWvfDSy;0ljuB{rqv>(y89bWUhb+xmj$elhFCmtegyC6RFfZaUoWY`b2gD)x+vD*9L z!!x;JH*V~b6v3mtN%5b$bm!SBP_E7FURM(mQ5&AeZmJU`eNdWCiek4ec3;g_?o34P ztUc@-nR7G5L~9^3z39-oFIG!ZG}akAy{a645vOr>u+^OyTMMx#`7S?+NZroZ!}aV( z=FT;>PGhyZFKO_Jiqq0mo}w3LR91jiX>r?3Y^MIWsR|D5G`iXIUZCV0MSBrhcm;e0 zO39OZ}3Jyhu>O{{{l42$Mp;}~zl^Vn4)XGI9-~>q9juREFL+iIw_a=|^fx7r2 zb_(s?9pK7DgzlnPE!n|#i{2co2B+C#Qo9ZJJ7Y+&nRhC=FHDSZ{HN8 zx&`jE(!Ie#JK~w02R@t%dKIVbBywjjLHpDbrLNUlHF1FR z8I5o1@Lk@sE6BbMj}R@XK`UPCFwd#Z#41uU8_8p=+1w7cyJ4@%-jDQR)hTL_KRX3t z2xE*|wdSr4*tut0hVoEm$>>q23G0Voxpr42Xo%9#OT^fA%B-|Y!8&0Q{YpXV?;#41UT*A^qv7TJ3TfR(&8c7}IbIhtAOf|Z-S z?dLjM(L!QuvobPzE75&u&K0BdI^@ zO({B;GFt27$}(p59lWZyi>#Gr8ywo{cZM&2qR{B`Qi`&)cjk1{j-*{|Hz(}8YTtI! zj&c1*(2+en>j<~Z&3p3Y1l)XNzO4y9+fHmzf5s{4iNefvQj<3^Ub-4#T@2e9}9;# z&n+Qmif&TG$QI*@{j*)rbAMeN;ha%C8GSs~(Vky=^5z`JeuUM!eMqZ4GnhzFYSJ>Z zSt~o|lRGWOiIo}GiJZF!YR-+%mf+_dh{aBT(NWYOmR5Iqf+*K$V3rlj=?8H>Et>Fr zdY4wH@S(~j9>N!)tP-Vdj+D2ZsF$`Q&QwR|q9@oRED$&CSeeVkC!z*pigfgKJLNt2oqGjw7GTHB9R@cE z?3+o&{O#t44?W!28Dq7`T3@hEiE$-%2#qCTXzK(sfw(1hLgZR`x~H3iFYQu~i+eWO zqVX}tW&K;L)Zb%X*bO~5EA)hBxU)ZK|0s5`MSkX2tI9~z{9r%Od+uU?PQ4$5qSGN! zf)d-pLn|>(>f=(4c|oMRpLe?>WtKI^+W(V_ST*=niAv9m7xfvVwDxJ|)XKvgtJdQ5 zT{<30*YA3TDAc}E#7S=G*JE$y+1Lk(*}!}!f7T14Yx~(w|C~J(g&iUzW<*KV_(0^z zXd<0xHIc5CvJ+X@$MPz*7csnux&#j02kXrF&Fvyxdphwad!p7(&feW!uf<*>j(0*E z4xzpg; z+-k9tvkN~nHXGmKu8)SkBz4F+hm%cidqDZ1+n<)Cd z-4LU-u|^8&%eboFIsbEJ{C@C2DS8+aoq8G{%@)}}ReWK#_o1xKRH6=JU^DM_F6Ta& z+1<{OhdU?Ik(zb3zww!Q%W6YJu3wnZl$8B9^=UWM{dQ+C(lRPYS2Q7Vw6oh9{@RQi z@zO!g-?1@ee_UDmnz``^9I64cbfl+D&GQ+~77>wW7U9PnEbW+;#2(g1>am{lIMp$u zdS+2W+~bM7*(ESLYR_&-Ik^&{*&mEmnb}ZHiJ`@!=0+*%@AfGb#*XEh&o*r@#Zkec>; z{4{@hp;H!fp?8Vv3)+Z$>F**JIdt2?{;Ia=B+kFES`o)sKWHyfQ->mLQBAZVE!FsG zOfyPoW6spoh&5eAp~e?+uUOP)cClha(|+TwqW}wq1~I?|42%!P93o_dTZRt#2P;_Z$ZT}hCs((o=Bb!VdWT*Zbti_j!xwe$ zoJ1eiBGi={G+RhbJSe7cMixE8NNaR4VtB@C4snImn0ITr#b@p_qKft351O;%=7zXd z=|4z8N2}M@??wp#%d$+9Gn}g;e;#E`X&3zE(Z%$I}%uCVA-Ryr9?dfyIUuUJFb}85; zcM9Nck==6pJl52r7^7R9fjb?EJrFe)Hze)Izs1yHHB$$_x~Xpkp`F_MbRXF~Eq894 z#A%VATj2fnZWXyz>&(NBopN?VzbsUn*6i7p?A=-l#oE6h~fwev2jrEuuITW<$? z*0%PrjP+WFTOsjNC*0}rZW+J20q69gKku+N5v3WY9NOgpsL7pYbx!0yh%;30!*P4b zJN?`R6+s=tAM`sd&R&i)4L3ji)CupFaTm?4UFQ#WVPeH8_BT&Dj~11QZsl$hl-yf% zLKSDIPLbRvcN@i8Of0Xp*!|a1+!%76=qB`V9!k@@SbSAPZ+&DOixrC;r$4!!CgL`-x>?{v+PcBsqx?Cc^$z98nUeLcp8;HlxZb=gGIgK8 zJ8f%_l6?RxOLr5U(0X5oJ2vXl`LH#ba{%MDnZc{|Jk|@nkeicCC$w(od%v=Kk@i0A z7#O7^j;Mz}YZbc#qIj!Vdymf9VsL<>sDZyayppPxS`x)f5Zufy3C{adI2`)$T+4sX*StZ#@=~XPm%UowzOBF(cMK z+*vf1#mxn4Y2&6C!~AcpVaM7HN%5W?PxG99?Oaj4nFZ|?xMd?6j58|z)_>wkHDr$< z&Y`8|wAfySy(Q?6mXuGNZp**zz5 zvN$5nZ`=Zr)=*;SApBjAv`3-$+0k{{AXXK(##&4L7_szw^=C&gVi>tKyT@&4EzD`J z6|EXH-^OXCz94tzKy!vU*xYY7UipiW?7PK|r`X-jnO#*o|IXs<%X@!}T|0kkW#P7W zQ_!FJQ^c;9nQxV&{w_5wreBDicK_|viQ(;!Tk*vTU5|*^%$-Gf(+}f)Ms^O2)gpfT zAYx4`6ZfCIbIf_PIX&)YILT3a;xa23V~gn6{x!)35RG&3$%mfeuU91Mi;ed7shxHJ9Xk)B@?;xGr{bixryyPF;X)-=?hMcjdoT> zW_ELmwO5=@=?zXy-N?{B)t&yXH;5wQ_CmtFe$DWuFIY`_zKE%fElSc%(J@ca*RAB; zUaSt!QLaI?#v4EDGoHUxPetdB#V0|MwZyAGqS|KqkU>;Q|qA`?+-KH zSkK2erllC`6b{+NpTg*^SuU3d3HMbE4Syw^uDzG6(2$Vr#!U;gsu+ zO$oigsA~mR!u5NHj8h^v7NjG8<_PhjnA$#t9Uya_IYDYxv08eZYB<$5a!T3wrB0Qk z-EnIa>BYIQQ8S`yJDvJM$2L#gpi`Dc73(}>W-VuN@@*f&8de-D%^mP*PExut16k3= z`&IODw~{+Bytp!MAB&>BW754EGkV;&G$U(Wac*Nb#m{EbugpXGg0ajjFTZ9A^=fy( zTDC64OCyRXP}~yf*@G7`#Z3w2>+eMRv4dpS%e@?X4RNaB1j_xB*yHq>xF~M$h!o!s zUSM~{>fDSM=TYYMxc_MX-@~7*Xq}Xa9%998zs4@rUbxftqL!4Zc5g){T8q824iESK zH$S5;PB%n>-f`5iZ|UUJhjU`7i8by2#qAb540cz{2eFeXKlUK((QEsn8U3 ( sokoban -- gadget ) - create-engine >>engine - sokoban-gadget new swap >>sokoban ; - -:: get-dim ( sokoban level -- level w h ) - ! Look for maximum height and width of wall layout to determine size of board - level component get first states>> nth :> new_board - level - new_board [ first ] map supremum 1 + - new_board [ second ] map supremum 1 + ; - -: new-sokoban ( gadget -- gadget ) - ! Restarts sokoban without changing levels - dup sokoban>> engine>> swap - [ dup level>> get-dim ] change-sokoban - swap over sokoban>> swap >>engine >>sokoban ; - -:: window-size ( sokoban -- window-size ) - sokoban level>> :> level - sokoban level get-dim :> ( lev w h ) - 100 w * :> xpix - 100 h * :> ypix - { xpix ypix } ; - - -: update-sokoban ( gadget -- gadget ) - ! Changes to the next level of sokoban - dup sokoban>> engine>> swap - [ dup level>> 1 + get-dim ] change-sokoban - dup sokoban>> window-size >>window-dims - swap over sokoban>> swap >>engine >>sokoban ; - -M: sokoban-gadget pref-dim* ( gadget -- dim ) - sokoban>> window-size ; - ! drop { 700 800 } ; ! needs to be changed as well - -: update-status ( gadget -- ) - dup sokoban>> [ - [ "Level: " % level>> # ] - [ paused?>> [ " (Paused)" % ] when ] bi - ] "" make swap show-status ; - -M: sokoban-gadget draw-gadget* ( gadget -- ) - [ - [ dim>> first2 ] [ sokoban>> ] bi draw-sokoban - ] keep update-status ; - -: unless-paused ( sokoban quot -- ) - over sokoban>> paused?>> [ - 2drop - ] [ - call - ] if ; inline - -sokoban-gadget H{ - { T{ button-down f f 1 } [ request-focus ] } - { T{ key-down f f "UP" } [ [ sokoban>> move-up ] unless-paused ] } - { T{ key-down f f "LEFT" } [ [ sokoban>> move-left ] unless-paused ] } - { T{ key-down f f "RIGHT" } [ [ sokoban>> move-right ] unless-paused ] } - { T{ key-down f f "DOWN" } [ [ sokoban>> move-down ] unless-paused ] } - { T{ key-down f f "p" } [ sokoban>> toggle-pause ] } - { T{ key-down f f "n" } [ new-sokoban drop ] } -} set-gestures - -: tick ( gadget -- ) - dup sokoban>> update-level? [ - update-sokoban - relayout-window - ] [ - relayout-1 - ] if - ; - -M: sokoban-gadget graft* ( gadget -- ) - [ [ tick ] curry 100 milliseconds every ] keep timer<< ; - -M: sokoban-gadget ungraft* ( gadget -- ) - dup sokoban>> engine>> dispose - [ stop-timer f ] change-timer drop ; - -: sokoban-window ( -- ) - [ - - "sokoban" open-status-window - ] with-ui ; - -MAIN: sokoban-window diff --git a/extra/sokoban/sound/sound.factor b/extra/sokoban/sound/sound.factor deleted file mode 100644 index 7db45b6e8b..0000000000 --- a/extra/sokoban/sound/sound.factor +++ /dev/null @@ -1,18 +0,0 @@ -! Copyright (C) 2009 Joe Groff. -! See http://factorcode.org/license.txt for BSD license. -USING: accessors timers audio audio.engine audio.loader calendar -destructors io kernel locals math math.functions ranges specialized-arrays -sequences random math.vectors literals ; - - -IN: sokoban.sound - -: create-engine ( -- engine ) - f 10 ; - -:: play-beep ( engine -- ) - $[ "vocab:sokoban/resources/once.wav" read-audio ] :> once-sound - engine start-audio* - - engine T{ audio-source f { 0.0 0.0 0.0 } 1.0 { 0.0 0.0 0.0 } f } once-sound f - play-static-audio-clip drop ; diff --git a/extra/sokoban/summary.txt b/extra/sokoban/summary.txt deleted file mode 100644 index f5e5143269..0000000000 --- a/extra/sokoban/summary.txt +++ /dev/null @@ -1 +0,0 @@ -Graphical sokoban game diff --git a/extra/sokoban/tags.txt b/extra/sokoban/tags.txt deleted file mode 100644 index 09934571b3..0000000000 --- a/extra/sokoban/tags.txt +++ /dev/null @@ -1,3 +0,0 @@ -demos -applications -games -- 2.34.1