From 581f4b06e9d4380a68ecfec485481416fc9632b4 Mon Sep 17 00:00:00 2001 From: kdrzazga Date: Sat, 28 Dec 2024 10:12:56 +0100 Subject: [PATCH] Electrician 15: Level 5 (spiders!!!) (#96) --- other/electrician/files/classdef.js | 22 +- other/electrician/files/creators.js | 397 ++++++++++++++----------- other/electrician/files/electrician.js | 2 +- other/electrician/files/levels.js | 29 +- other/electrician/files/spider.png | Bin 5123 -> 5330 bytes 5 files changed, 265 insertions(+), 185 deletions(-) diff --git a/other/electrician/files/classdef.js b/other/electrician/files/classdef.js index 3d5ed1d..cd51b5a 100644 --- a/other/electrician/files/classdef.js +++ b/other/electrician/files/classdef.js @@ -183,7 +183,7 @@ class Wire { calculateY(floor1, floor2) { const y1 = floor1?.sprite.y || 0; - const y2 = floor2 ? floor2.sprite.y : 0; + const y2 = floor2?.sprite.y || 0; return (y1 + y2) / 2; } @@ -266,7 +266,7 @@ class Enemy { } } -class Bat extends Enemy{ +class Bat extends Enemy { static MOVE_RADIUS = 280; constructor(id){ @@ -390,39 +390,39 @@ class FloorBuilder { return this; } - withCeilingConnector(connectorSlot){ - this.floor.ceilingConnectors.push(connectorSlot); + withCeilingConnectors(connectorSlotsArray){ + this.floor.ceilingConnectors.push(...connectorSlotsArray); return this; } - withBottomConnector(connectorSlot) { - this.floor.bottomConnectors.push(connectorSlot); + withBottomConnectors(connectorSlotsArray) { + this.floor.bottomConnectors.push(...connectorSlotsArray); return this; } withLampInCenter() { const lampConnectorX = Math.floor(Floor.WIDTH/Wire.SLOT_SIZE /2); - this.withCeilingConnector(lampConnectorX); + this.withCeilingConnectors([lampConnectorX]); return this; } withTVInCenterLeft(){ const tvConnectorX = 12; - this.withBottomConnector(tvConnectorX); + this.withBottomConnectors([tvConnectorX]); return this; } withFridgeOnLeft(){ const fridgeConnectorSlot = 2; - this.withCeilingConnector(fridgeConnectorSlot); + this.withCeilingConnectors([fridgeConnectorSlot]); return this; } withKitchenSegmentOnRight(){ const fridge2ConnectorSlot = 29; const fanConnectorSlot = 26; - this.withCeilingConnector(fridge2ConnectorSlot); - this.withCeilingConnector(fanConnectorSlot); + this.withCeilingConnectors([fridge2ConnectorSlot]); + this.withCeilingConnectors([fanConnectorSlot]); return this; } } diff --git a/other/electrician/files/creators.js b/other/electrician/files/creators.js index a8ad176..f5e3631 100644 --- a/other/electrician/files/creators.js +++ b/other/electrician/files/creators.js @@ -3,15 +3,14 @@ class Creator { static HIGH_FLOOR_LEVEL = 104; static LOW_FLOOR_LEVEL = 438; - static createEnemies(ratsData, batsData, spidersData, physics){ - let enemies = []; - const rats = ratsData.map(data => Creator.createEnemy(Rat, data, physics)); - const bats = batsData.map(data => Creator.createEnemy(Bat, data, physics)); - const spiders = spidersData.map(data => Creator.createEnemy(Spider, data, physics)); - - enemies.push(...rats, ...bats, ...spiders); - return enemies; - } + static createEnemies(ratsData, batsData, spidersData, physics) { + const createEnemy = (classType, data) => Creator.createEnemy(classType, data, physics); + return [].concat( + ratsData.map(data => createEnemy(Rat, data)), + batsData.map(data => createEnemy(Bat, data)), + spidersData.map(data => createEnemy(Spider, data)) + ); + } static createEnemy(EnemyClass, data, physics, positionAdjustment = 0) { const enemy = new EnemyClass(data.id); @@ -32,138 +31,158 @@ class Creator { } if (data.velocity) enemy.sprite.velocity = data.velocity; + if (data.speed) enemy.speed = data.speed; return enemy; } - //Level 1 - static create3storeBuilding(physics) { - let building = new Building('House'); - building.init(physics); // Initializes ladder and power lines + static createLevel(levelJson, physics){ + let building = new Building(levelJson.building.name); + building.init(physics); - const floorBuilder1 = new FloorBuilder(); - building.floors.push(floorBuilder1.withName('attic').withBottomConnector(3).withBottomConnector(11) - .withCeilingConnector(5).withCeilingConnector(25).withBottomConnector(28).build()); + levelJson.building.floors.forEach(floorData => { + let floorBuilder = new FloorBuilder(); - const floorBuilder2 = new FloorBuilder(); - building.floors.push(floorBuilder2.withName('living room').withCeilingConnector(2).withCeilingConnector(29) - .withLampInCenter().withTVInCenterLeft().build()); + floorBuilder = floorBuilder.withName(floorData.name); - const kitchenBuilder = new FloorBuilder(); - building.floors.push(kitchenBuilder.withName('kitchen').withFridgeOnLeft().withLampInCenter().withKitchenSegmentOnRight().build()); + if (floorData.bottomConnectors) { + floorBuilder = floorBuilder.withBottomConnectors(floorData.bottomConnectors); + } - building.floors.forEach(floor => floor.init(physics)); - building.floors.forEach(floor => floor.calculateFloorLevel()); + if (floorData.ceilingConnectors) { + floorBuilder = floorBuilder.withCeilingConnectors(floorData.ceilingConnectors); + } - const connectionPointsCounts = [2, 6, 5]; - building.wires = building.floors.map((floor, index) => { - const aboveFloor = building.floors[index] || null; - const belowFloor = building.floors[index - 1] || null; - return new Wire(index, physics, belowFloor, aboveFloor, connectionPointsCounts[index]); + const newFloor = floorBuilder.build(); + newFloor.init(physics); + building.floors.push(newFloor); }); - building.includeWiresInInfoFrame(); - const MID_FLOOR_LEVEL = 328 - Floor.HEIGHT / 2; - - const ratsData = [ - { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL }, - { id: 2, active: true, y: Building.GROUND_FLOOR_LEVEL, minX: Floor.WIDTH / 2, maxX: 2 * Floor.WIDTH / 3, velocity: { x : 3} }, - { id: 3, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 1.4 } }, - { id: 4, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, - { id: 5, active: true, y: MID_FLOOR_LEVEL, minX: 2 * Floor.WIDTH / 4, maxX: 1.15*Floor.WIDTH, velocity: { x: 1.4 }, wireId: 1 }, - { id: 6, active: true, y: MID_FLOOR_LEVEL, minX: 2 * Ladder.WIDTH, velocity: { x: 0.85}, wireId: 1 }, - { id: 7, active: true, y: Creator.HIGH_FLOOR_LEVEL, minX: Floor.WIDTH / 3 + 30, maxX: 1.15*Floor.WIDTH, wireId: 0 } - ]; - - const batsData = [ - { id: 0, active: true, speed: -0.017 }, - { id: 1, active: true, currentAngle: Math.PI / 2, /*speed: 0.001*/ } - ]; - - const spidersData = [ - ]; - - building.enemies = Creator.createEnemies(ratsData, batsData, spidersData, physics); - - return building; - } - - //Level 2 - static createOfficeGymGarage(physics){ - let building = new Building('Office Gym Garage'); - building.init(physics); // Initializes ladder and power lines - - const officeBuilder = new FloorBuilder(); - building.floors.push(officeBuilder.withName('office').withBottomConnector(5).withBottomConnector(9) - .withBottomConnector(13).withBottomConnector(16).withBottomConnector(19).withBottomConnector(26) - .withCeilingConnector(5).withCeilingConnector(12).withCeilingConnector(20).withCeilingConnector(26).build()); - - const gymBuilder = new FloorBuilder(); - building.floors.push(gymBuilder.withName('gym').withCeilingConnector(7).withCeilingConnector(23) - .build()); - - const garageBuilder = new FloorBuilder(); - building.floors.push(garageBuilder.withName('garage').withCeilingConnector(5).withCeilingConnector(20) - .withCeilingConnector(22).withCeilingConnector(29).build()); - - building.floors.forEach(floor => floor.init(physics)); building.floors.forEach(floor => floor.calculateFloorLevel()); - const connectionPointsCounts = [4, 8, 4]; + const ratsData = levelJson.building.enemies.rats; + const batsData = levelJson.building.enemies.bats; + const spidersData = levelJson.building.enemies.spiders; + building.enemies = Creator.createEnemies(ratsData, batsData, spidersData, physics); + building.wires = building.floors.map((floor, index) => { const aboveFloor = building.floors[index] || null; const belowFloor = building.floors[index - 1] || null; - return new Wire(index, physics, belowFloor, aboveFloor, connectionPointsCounts[index]); + return new Wire(index, physics, belowFloor, aboveFloor, levelJson.building.connectionPointsCounts[index]); }); building.includeWiresInInfoFrame(); - //const MID_FLOOR_LEVEL = 328 - Floor.HEIGHT / 2; - const ratsData = [ - { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL } - ]; - - const batsData = [ - { id: 0, active: true, speed: 0.007 }, - { id: 1, active: true, speed: 0.006 }, - { id: 3, active: true, speed: 0.005 }, - { id: 4, active: true, speed: 0.004 }, - { id: 5, active: true, speed: 0.008 }, - { id: 6, active: true, speed: 0.0053 }, - { id: 7, active: true, speed: 0.009 }, - { id: 8, active: true, speed: 0.0042 }, - ]; + return building; + } - const spidersData = [ - ]; - - building.enemies = Creator.createEnemies(ratsData, batsData, spidersData, physics); + static createLevel1(physics){ + const buildingData = { + "building": { + "name": 'Dwelling 1', + "floors": [ + { + "name": "floor2", + "bottomConnectors": [23, 24, 25], + "ceilingConnectors": [7, 12, 23] + }, + { + "name": "power-room", + "ceilingConnectors": [7, 12, 19, 20, 21, 26, 27, 28] + }, + { + "name": "basement", + "ceilingConnectors": [7, 12, 23] + } + ], + "enemies":{ + "rats": [ + { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL }, + { id: 2, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, + //{ id: 4, active: true, y: MID_FLOOR_LEVEL, velocity: { x: 0.85}, wireId: 1}, + { id: 3, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0} + ], + + "bats": [ + { id: 0, active: true, speed: -0.007 } + ], + + "spiders": [] + }, + "connectionPointsCounts": [3, 11, 3] + } + }; + + let building = Creator.createLevel(buildingData, physics); + return building; + } - return building; + static createLevel2(physics){ + + const buildingData = { + "building": { + "name": 'Office Gym Garage 1', + "floors": [ + { + "name": "office", + "bottomConnectors": [5, 9, 13, 16, 19, 26], + "ceilingConnectors": [5, 12, 20, 26] + }, + { + "name": "gym", + "ceilingConnectors": [7, 23] + }, + { + "name": "garage", + "ceilingConnectors": [5, 20, 22, 29] + } + ], + "enemies":{ + "rats": [ + { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL } + ], + + "bats": [ + { id: 0, active: true, speed: 0.007 }, + { id: 1, active: true, speed: 0.006 }, + { id: 2, active: true, speed: 0.005 }, + { id: 3, active: true, speed: 0.004 }, + { id: 4, active: true, speed: 0.008 }, + { id: 5, active: true, speed: 0.0053 }, + { id: 6, active: true, speed: 0.009 }, + { id: 7, active: true, speed: 0.0042 } + ], + + "spiders": [] + }, + "connectionPointsCounts" : [4, 8, 4] + } + }; + + let building = Creator.createLevel(buildingData, physics); + return building; } - //Level 3 - static createBuilding(physics){ - let building = new Building('Home 2'); - building.init(physics); // Initializes ladder and power lines + static createLevel3(physics) { - const atticBuilder = new FloorBuilder(); - building.floors.push(atticBuilder.withName('floor2').withCeilingConnector(7).withCeilingConnector(12) - .withCeilingConnector(23).withBottomConnector(23).withBottomConnector(24).withBottomConnector(25).build()); + let building = new Building('House'); + building.init(physics); // Initializes ladder and power lines - const gymBuilder = new FloorBuilder(); - building.floors.push(gymBuilder.withName('power-room').withCeilingConnector(7).withCeilingConnector(12) - .withCeilingConnector(19).withCeilingConnector(20).withCeilingConnector(21).withCeilingConnector(26) - .withCeilingConnector(27).withCeilingConnector(28).build()); + const floorBuilder1 = new FloorBuilder(); + building.floors.push(floorBuilder1.withName('attic').withBottomConnectors([3, 11, 28]) + .withCeilingConnectors([5, 25]).build()); - const garageBuilder = new FloorBuilder(); - building.floors.push(garageBuilder.withName('basement').withCeilingConnector(7).withCeilingConnector(12) - .withCeilingConnector(23).build()); + const floorBuilder2 = new FloorBuilder(); + building.floors.push(floorBuilder2.withName('living room').withCeilingConnectors([2, 29]) + .withLampInCenter().withTVInCenterLeft().build()); + + const kitchenBuilder = new FloorBuilder(); + building.floors.push(kitchenBuilder.withName('kitchen').withFridgeOnLeft().withLampInCenter().withKitchenSegmentOnRight().build()); building.floors.forEach(floor => floor.init(physics)); building.floors.forEach(floor => floor.calculateFloorLevel()); - const connectionPointsCounts = [3, 11, 3]; + const connectionPointsCounts = [2, 6, 5]; building.wires = building.floors.map((floor, index) => { const aboveFloor = building.floors[index] || null; const belowFloor = building.floors[index - 1] || null; @@ -171,17 +190,21 @@ class Creator { }); building.includeWiresInInfoFrame(); + const MID_FLOOR_LEVEL = 328 - Floor.HEIGHT / 2; - //const MID_FLOOR_LEVEL = 328 - Floor.HEIGHT / 2; const ratsData = [ { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL }, - { id: 2, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, - //{ id: 4, active: true, y: MID_FLOOR_LEVEL, velocity: { x: 0.85}, wireId: 1}, - { id: 3, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0} + { id: 2, active: true, y: Building.GROUND_FLOOR_LEVEL, minX: Floor.WIDTH / 2, maxX: 2 * Floor.WIDTH / 3, velocity: { x : 3} }, + { id: 3, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 1.4 } }, + { id: 4, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, + { id: 5, active: true, y: MID_FLOOR_LEVEL, minX: 2 * Floor.WIDTH / 4, maxX: 1.15*Floor.WIDTH, velocity: { x: 1.4 }, wireId: 1 }, + { id: 6, active: true, y: MID_FLOOR_LEVEL, minX: 2 * Ladder.WIDTH, velocity: { x: 0.85}, wireId: 1 }, + { id: 7, active: true, y: Creator.HIGH_FLOOR_LEVEL, minX: Floor.WIDTH / 3 + 30, maxX: 1.15*Floor.WIDTH, wireId: 0 } ]; const batsData = [ - { id: 0, active: true, speed: -0.007 } + { id: 0, active: true, speed: -0.017 }, + { id: 1, active: true, currentAngle: Math.PI / 2, /*speed: 0.001*/ } ]; const spidersData = [ @@ -192,64 +215,102 @@ class Creator { return building; } - //Level 4 - static createElectronicsStore(physics){ - let building = new Building('Electronics Store'); - building.init(physics); // Initializes ladder and power lines - - const musicFloorBuilder = new FloorBuilder(); - building.floors.push(musicFloorBuilder.withName('music-floor').withCeilingConnector(6).withCeilingConnector(19) - .withBottomConnector(3).withBottomConnector(9).withBottomConnector(14).withBottomConnector(17) - .withBottomConnector(21).withBottomConnector(25).withBottomConnector(28).build()); - - const computerRoomBuilder = new FloorBuilder(); - building.floors.push(computerRoomBuilder.withName('computer-room').withCeilingConnector(2).withCeilingConnector(7) - .withCeilingConnector(12).withCeilingConnector(20) - .withBottomConnector(26).build()); - - const groundFloorBuilder = new FloorBuilder(); - building.floors.push(groundFloorBuilder.withName('computer-room2').withCeilingConnector(5).withCeilingConnector(12) - .withCeilingConnector(12).withCeilingConnector(15).withCeilingConnector(19).withCeilingConnector(25).build()); - - building.floors.forEach(floor => floor.init(physics)); - building.floors.forEach(floor => floor.calculateFloorLevel()); - - const connectionPointsCounts = [2, 11, 6]; - building.wires = building.floors.map((floor, index) => { - const aboveFloor = building.floors[index] || null; - const belowFloor = building.floors[index - 1] || null; - return new Wire(index, physics, belowFloor, aboveFloor, connectionPointsCounts[index]); - }); - - building.includeWiresInInfoFrame(); - - //const MID_FLOOR_LEVEL = 328 - Floor.HEIGHT / 2; - const ratsData = [ - { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.7 } }, - { id: 2, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.8 } }, - { id: 3, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.9 } }, - { id: 4, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, - { id: 5, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0}, - { id: 6, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0, velocity: { x: 0.97 } } - ]; - - const batsData = [ - { id: 0, active: true, speed: -0.007 }, - { id: 1, active: true, speed: -0.006 }, - { id: 2, active: true, speed: 0.003 } - ]; - - const spidersData = [ - { id: 1, active: true, y: 25, velocity: { y: 0.5 } } - ]; - - building.enemies = Creator.createEnemies(ratsData, batsData, spidersData, physics); + static createLevel4(physics){ + const buildingData = { + "building": { + "name": 'Dwelling 1', + "floors": [ + { + "name": "music-floor", + "bottomConnectors": [3, 9, 14, 17, 21, 25, 28], + "ceilingConnectors": [6, 19] + }, + { + "name": "computer-room", + "bottomConnectors" : [26], + "ceilingConnectors": [2, 7, 12, 20] + }, + { + "name": "computer-room2", + "ceilingConnectors": [5, 12, 15, 19, 25] + } + ], + "enemies":{ + "rats": [ + { id: 1, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.7 } }, + { id: 2, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.8 } }, + { id: 3, active: true, y: Building.GROUND_FLOOR_LEVEL, velocity: { x: 0.9 } }, + { id: 4, active: true, y: Creator.LOW_FLOOR_LEVEL, velocity: { x: 0.7 }, wireId: 2}, + { id: 5, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0}, + { id: 6, active: true, y: Creator.HIGH_FLOOR_LEVEL, wireId: 0, velocity: { x: 0.97 } } + ], + + "bats": [ + { id: 0, active: true, speed: -0.007 }, + { id: 1, active: true, speed: -0.006 }, + { id: 2, active: true, speed: 0.003 } + ], + + "spiders": [{ id: 1, active: true, y: 25, velocity: { y: 0.5 } }] + }, + "connectionPointsCounts" : [2, 11, 6] + } + }; + + let building = Creator.createLevel(buildingData, physics); + return building; + } - return building; + static createLevel5(physics){ + const buildingData = { + "building": { + "name": 'Spider Dwelling', + "floors": [ + { + "name": "music-floor", + "bottomConnectors": [], + "ceilingConnectors": [] + }, + { + "name": "computer-room", + "bottomConnectors" : [], + "ceilingConnectors": [] + }, + { + "name": "computer-room2", + "ceilingConnectors": [] + } + ], + "enemies":{ + "rats": [ + ], + + "bats": [ + { id: 0, active: true, speed: -0.009 }, + { id: 1, active: true, speed: -0.010 } + ], + + "spiders": [ + { id: 1, active: true, y: 25, speed : 0.7}, + { id: 2, active: true, y: 25, speed : 3}, + { id: 3, active: true, y: 25, speed : 1.1}, + { id: 6, active: true, y: 25, speed : 0.6}, + { id: 8, active: true, y: 25, speed : 0.9}, + { id: 10, active: true, y: 25, speed : 1}, + { id: 12, active: true, y: 25, speed : 1.8}, + ] + }, + "connectionPointsCounts" : [0, 0, 0] + } + }; + + let building = Creator.createLevel(buildingData, physics); + return building; } } class FrameCreator{ + static createLevel2ExtraInfoFrameContent(){ const content = "

Retro computers:
" + "
Commodore 64
" diff --git a/other/electrician/files/electrician.js b/other/electrician/files/electrician.js index 4dbfc8d..be66f37 100644 --- a/other/electrician/files/electrician.js +++ b/other/electrician/files/electrician.js @@ -1,4 +1,4 @@ -const levelsJson = {'lvl1' : Level1Scene, 'lvl2': Level2Scene, 'lvl3': Level3Scene, 'lvl4': Level4Scene} +const levelsJson = {'lvl1' : Level1Scene, 'lvl2': Level2Scene, 'lvl3': Level3Scene, 'lvl4': Level4Scene, 'lvl5': Level5Scene } let level = sessionStorage.getItem("level"); let levelObject = Level1Scene; diff --git a/other/electrician/files/levels.js b/other/electrician/files/levels.js index d30c195..0d3d3d1 100644 --- a/other/electrician/files/levels.js +++ b/other/electrician/files/levels.js @@ -252,7 +252,7 @@ class Level1Scene extends LevelScene { } create() { - super.create(Creator.createBuilding); + super.create(Creator.createLevel1); } } @@ -270,7 +270,7 @@ class Level2Scene extends LevelScene{ } create() { - super.create(Creator.createOfficeGymGarage); + super.create(Creator.createLevel2); const content = FrameCreator.createLevel2ExtraInfoFrameContent(); this.showExtraInfoFrame(content); } @@ -290,7 +290,7 @@ class Level3Scene extends LevelScene{ } create(){ - super.create(Creator.create3storeBuilding); + super.create(Creator.createLevel3); } } @@ -298,7 +298,7 @@ class Level4Scene extends LevelScene{ constructor() { super('Level4'); - this.nextLevel = 'lvl1'; + this.nextLevel = 'lvl5'; this.extraInfoFrameVisible = "left: 85%; visibility: show" } @@ -309,8 +309,27 @@ class Level4Scene extends LevelScene{ } create() { - super.create(Creator.createElectronicsStore); + super.create(Creator.createLevel4); const content = FrameCreator.createLevel4ExtraInfoFrameContent(); this.showExtraInfoFrame(content); } } + +class Level5Scene extends LevelScene{ + + constructor() { + super('Level5'); + this.nextLevel = 'lvl1'; + this.extraInfoFrameVisible = "left: 85%; visibility: show" + } + + loadFloorImages(){ + this.load.image('floor0', 'files/room-wide-web.png'); + this.load.image('floor1', 'files/room-wide-web2.png'); + this.load.image('floor2', 'files/room-wide-web.png'); + } + + create() { + super.create(Creator.createLevel5); + } +} diff --git a/other/electrician/files/spider.png b/other/electrician/files/spider.png index 2057dc7ed71751e537b5288c791fd1f9467b4155..639dc465d75fb0d867aa4f039ab0e8b16bef6fcb 100644 GIT binary patch delta 1203 zcmV;k1WfybDAFmABmu~gB{>6N%$<>86o0~SqK! zU>+^1kS)0)|5di>^ z^df(LR2=Le>X4y2*+oShOBIV?p|llRbuhW~3z{?}DK3tJYr(;f#j1mgv#t)Vf*|+- z;_Tq0=prTlFDbN$@!+^0@9sVB-T^|R!c?;>3aFZ8q~b9#n_CqFuLxok{Rp5}Vy2!* zFJ|C5zV6}U>s^Frd7t}p3@CY%0X~s9%5;CjBHkdL-L!Ph`@|tuk`&@|;z@%pNc_lk z+2uFRMTZ5R88R}ddEyYUSnOcAgIUQ?iD!tzimFk*kabz%yv13q)L84D{Dr~1wvy&L z%`wEWganchA)|&eDzFftRU^ejiuPk3{t?HYB$rICG8j1)P=yM~@q_=t?{3Y)^pt;_ z6pR7gFSh+L4g_|AX5F^Gk8Qho0{EYSE3NIXHh{TL((7$4d;|<`0~gnAP2K}8cYxt1 zT{0v`^3xOw1>pURz9|O`-2#1UZf~u9oIU^<>T3B0I5-3*ij=+X@$R0^-u^w)>hA|* zGIF3^&+5wn01y*tR9JLaO-wptZ*8-a0)GM|GC5>pF<~}iEi`2@Wi2#gH!v+?H85f= zFfcGTI51{4VKri6lQspa3o|e?GBG(hG&VOdlj{X^2r)A{G%z|bIg@7wCI~SzIy5jk zF*&o92Fn7I!v{hEJ5YTw!(Fca%-`X^=y6`?P@%TJ#E9A~gog=m2 zWtHC-!?o@661mPw{?iO|78ZIANpnG&wiT|NKSabzRKN=(O{t{^^#f0!wAnL%7nH~A zIXqrZ^6%ZI0_{)+Zw_jO<~}cR#2m6vt{Uuzrt7?n-)Iu0R`lATDUF!3zsL8GyNRTr zl{hI~#1s*bD}72>j4_fH1puIwE$kRj>pCt-%h1gE!UjhLs3k@zr>SIshALq~qzO=( zs>J#1u5|IPe%w7@oUHEz$^B1%Hx&xTE^Dt`NiL^DIPB}=vzWcq{ikh(Y=xrT{*-{D z0xwPl9>C>>y<_R>+-+1n_zBCq6jF;hD!|cdg>xeW?6~$m9ES!CiyVy2Cc#llLNjn! zh*|DAjLmMC!<0N|#Jk5-K+bcm4va=FAnOuMvrPgHpxTUbx|PeJEcHTusb_Bh#NMK*aTf9hTgeW~@VxG8)N(lTMuPdR~wmrgz5$oevZe@R Rc$5GD002ovPDHLkV1j6sD;WR) delta 1165 zcmV;81akY*DT64GBmu{fB{>6}F^7?16o15Uq75e0!2?oLqkA1rfukh7b6%}v|52yY zU>+^9e3JS*_Mt`=0!T!GgAu;X2Jx zB(Q`eQV=1djtZ)<5T#Wk#YCF+;~xI7<4=)GCRYWF91EyHh2;3b|KNAGW^sDTe@zO; zf!-I}{ul!SyFja9+uz5w-8upM&%l+|@zy9Sx0hc?#@RKeX zk|X(P3dJJuen#Jv2ZnBe{x!F^_C8J@fGl;jd;=UD0^=phUiWx+Uw3c+o@w{@1LUl7 z)bWdKyZ`_XG-*^=bXZMHI%98bvy=jV0wgwOH#lN8G&3zTWHUA`G%#f_En;LcHZ3qP zG&40aIALKqH)fMJ1*!`&I5jpjHZ?LZFgKIz1#}27I65>pIx;qsXa*(-FgQ9iH##yl zvz7+S0<%C0UYtumM#^-Uoug6OW zkh?B*4cDBNReoL!({>)mJJngvZ<=9F!(7iHsV*o>2(ah;Dk55<0#+D*X-X|Es2^AY zCC#3?pj@uE;c~s9&v%;&q(j+jJN)tXN;)sOP(HR|8p?G9`>yFaFXMMKiDD~y>Ak~^ zn61C-XP0{jr=aCH$z8-05s)i=N?4qx3AHHmJVPm4vF`v|*HJ-ghGxzeGB_+iDKSbp zjU@vlR4FDzk^s4>ik;7YYNd;3^`q|j;$&SDB&+=Dp+bqVOWG@Yl8d#|_xt1c>*ceU zz0~uU5FlHjNLnd4Eb!t~U;$ii*y~GIr?z4B;1QO!6jF*gEI_ZhuejGq?MFW}XtBtN zvDqXzY)L2%E)`OmdoIRiH_XM9+)2c{#Z-XKbFB`HJQa|3i6+^9CV2{=y*|rYNG4kz z?2V`ZrHf@$v&!joj|@xnn87-*y<#2XujuqkYd}QxgB+IBmu9p>4>KCcg5yq{YyDr4 z9H*Crp%hSwfmF;_&;)gKR{+#FZUyMCmPhmLxuY0#JptQVS1-10Nph`J`W!`Omo}Ce f>#i~VbM^xc?XgJ^a)-|W00000NkvXXu0mjfCOH?Q